From 6805ee650412baf6346d9d7cc3aa3a2a09f9bc01 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 2 Feb 2016 15:27:17 +0300 Subject: [PATCH 01/34] GridNearLockRequestV2 example implementation. --- .../communication/GridIoMessageFactory.java | 20 +- .../processors/cache/GridCacheIoManager.java | 8 +- .../GridDistributedLockRequest.java | 7 +- .../dht/GridDhtTransactionalCacheAdapter.java | 67 +- .../dht/colocated/GridDhtColocatedCache.java | 8 +- .../colocated/GridDhtColocatedLockFuture.java | 38 +- .../distributed/near/GridNearLockFuture.java | 123 ++-- .../distributed/near/GridNearLockRequest.java | 586 ++--------------- .../near/GridNearLockRequestV1.java | 596 ++++++++++++++++++ .../near/GridNearLockRequestV2.java | 583 +++++++++++++++++ .../near/GridNearLockResponse.java | 322 +--------- .../near/GridNearLockResponseV1.java | 330 ++++++++++ .../near/GridNearLockResponseV2.java | 310 +++++++++ .../near/GridNearTransactionalCache.java | 11 +- .../IgniteClientReconnectAtomicsTest.java | 10 +- .../IgniteClientReconnectCacheTest.java | 4 +- .../IgniteCacheNearLockValueSelfTest.java | 8 +- .../IgniteTxReentryAbstractSelfTest.java | 4 +- ...teCacheClientNodeChangingTopologyTest.java | 46 +- 19 files changed, 2112 insertions(+), 969 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.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 3c7f3781622be..f92d728445dcf 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 @@ -82,8 +82,10 @@ import org.apache.ignite.internal.processors.cache.distributed.near.CacheVersionedValue; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishRequest; @@ -417,12 +419,12 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 51: - msg = new GridNearLockRequest(); + msg = new GridNearLockRequestV1(); break; case 52: - msg = new GridNearLockResponse(); + msg = new GridNearLockResponseV1(); break; @@ -726,6 +728,16 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; + case 125: + msg = new GridNearLockRequestV2(); + + break; + + case 127: + msg = new GridNearLockResponseV2(); + + break; + // [-3..119] [124] - this // [120..123] - DR // [-4..-22] - SQL 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 b297827007672..6599ecc725b7f 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 @@ -50,8 +50,8 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest; @@ -484,9 +484,9 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 51: { - GridNearLockRequest req = (GridNearLockRequest)msg; + GridNearLockRequestV1 req = (GridNearLockRequestV1)msg; - GridNearLockResponse res = new GridNearLockResponse( + GridNearLockResponseV1 res = new GridNearLockResponseV1( ctx.cacheId(), req.version(), req.futureId(), 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 5d07b6faad974..f569346929d12 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 @@ -21,6 +21,7 @@ import java.util.ArrayList; 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; @@ -232,7 +233,7 @@ public boolean[] returnFlags() { * * @param skipStore Skip store flag. */ - private void skipStore(boolean skipStore){ + private void skipStore(boolean skipStore) { flags = skipStore ? (byte)(flags | SKIP_STORE_FLAG_MASK) : (byte)(flags & ~SKIP_STORE_FLAG_MASK); } @@ -301,6 +302,10 @@ public List keys() { return keys; } + public void keys(List keys) { + this.keys = keys; + } + /** * @return Max lock wait time. */ 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 ae24ed1a84296..214444a58d6b9 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 @@ -26,6 +26,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.UUID; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -48,7 +49,10 @@ import org.apache.ignite.internal.processors.cache.distributed.GridDistributedUnlockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache; @@ -73,6 +77,7 @@ import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.transactions.TransactionIsolation; import org.jetbrains.annotations.Nullable; @@ -133,8 +138,14 @@ protected GridDhtTransactionalCacheAdapter(GridCacheContext ctx, GridCache } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockRequestV2.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockRequestV2 req) { + processNearLockRequest(nodeId, req); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridNearLockRequestV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockRequestV1 req) { processNearLockRequest(nodeId, req); } }); @@ -865,12 +876,19 @@ public IgniteInternalFuture lockAllAsync( return new GridFinishedFuture<>(res); } + IgniteUuid miniId; + + if (req instanceof GridNearLockRequestV1) + miniId = ((GridNearLockRequestV1)req).miniId(); + else + miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); + tx = new GridDhtTxLocal( ctx.shared(), nearNode.id(), req.version(), req.futureId(), - req.miniId(), + miniId, req.threadId(), req.implicitTx(), req.implicitSingleTx(), @@ -940,7 +958,7 @@ public IgniteInternalFuture lockAllAsync( assert !t.empty(); // Create response while holding locks. - final GridNearLockResponse resp = createLockReply(nearNode, + final GridNearLockResponseV1 resp = createLockReply(nearNode, entries, req, t, @@ -952,7 +970,8 @@ public IgniteInternalFuture lockAllAsync( return t.commitAsync().chain( new C1, GridNearLockResponse>() { - @Override public GridNearLockResponse apply(IgniteInternalFuture f) { + @Override public GridNearLockResponse apply( + IgniteInternalFuture f) { try { // Check for error. f.get(); @@ -970,7 +989,7 @@ public IgniteInternalFuture lockAllAsync( else { sendLockReply(nearNode, t, req, resp); - return new GridFinishedFuture<>(resp); + return new GridFinishedFuture(resp); } } } @@ -992,7 +1011,7 @@ public IgniteInternalFuture lockAllAsync( else if (!b) e = new GridCacheLockTimeoutException(req.version()); - GridNearLockResponse res = createLockReply(nearNode, + GridNearLockResponseV1 res = createLockReply(nearNode, entries, req, null, @@ -1037,11 +1056,18 @@ private GridNearLockResponse sendClientLockRemapResponse(ClusterNode nearNode, AffinityTopologyVersion topVer) { assert topVer != null; - GridNearLockResponse res = new GridNearLockResponse( + IgniteUuid miniId; + + if (req instanceof GridNearLockRequestV1) + miniId = ((GridNearLockRequestV1)req).miniId(); + else + miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); + + GridNearLockResponseV1 res = new GridNearLockResponseV1( ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + miniId, false, 0, null, @@ -1072,7 +1098,7 @@ private GridNearLockResponse sendClientLockRemapResponse(ClusterNode nearNode, * @param err Error. * @return Response. */ - private GridNearLockResponse createLockReply( + private GridNearLockResponseV1 createLockReply( ClusterNode nearNode, List entries, GridNearLockRequest req, @@ -1082,12 +1108,19 @@ private GridNearLockResponse createLockReply( assert mappedVer != null; assert tx == null || tx.xidVersion().equals(mappedVer); + IgniteUuid miniId; + + if (req instanceof GridNearLockRequestV1) + miniId = ((GridNearLockRequestV1)req).miniId(); + else + miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); + try { // Send reply back to originating near node. - GridNearLockResponse res = new GridNearLockResponse(ctx.cacheId(), + GridNearLockResponseV1 res = new GridNearLockResponseV1(ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + miniId, tx != null && tx.onePhaseCommit(), entries.size(), err, @@ -1105,7 +1138,7 @@ private GridNearLockResponse createLockReply( int i = 0; - for (ListIterator it = entries.listIterator(); it.hasNext();) { + for (ListIterator it = entries.listIterator(); it.hasNext(); ) { GridCacheEntryEx e = it.next(); assert e != null; @@ -1196,10 +1229,10 @@ private GridNearLockResponse createLockReply( U.error(log, "Failed to get value for lock reply message for node [node=" + U.toShortString(nearNode) + ", req=" + req + ']', e); - return new GridNearLockResponse(ctx.cacheId(), + return new GridNearLockResponseV1(ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + miniId, false, entries.size(), e, @@ -1220,7 +1253,7 @@ private void sendLockReply( ClusterNode nearNode, @Nullable IgniteInternalTx tx, GridNearLockRequest req, - GridNearLockResponse res + GridNearLockResponseV1 res ) { Throwable err = res.error(); @@ -1402,7 +1435,7 @@ private void map(UUID nodeId, * @param nodes Nodes. * @param map Map. */ - @SuppressWarnings( {"MismatchedQueryAndUpdateOfCollection"}) + @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) private void map(GridCacheEntryEx entry, @Nullable Iterable nodes, Map> map) { 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 073043d71d321..54cd440afd8a4 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 @@ -55,7 +55,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture; import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal; @@ -150,8 +150,8 @@ public GridDhtColocatedCache(GridCacheContext ctx, GridCacheConcurrentMap } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV1 res) { processLockResponse(nodeId, res); } }); @@ -1076,7 +1076,7 @@ else if (!b) * @param nodeId Node ID. * @param res Response. */ - private void processLockResponse(UUID nodeId, GridNearLockResponse res) { + private void processLockResponse(UUID nodeId, GridNearLockResponseV1 res) { assert nodeId != null; assert res != null; 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 e4c6b712989e2..be9516bd587ee 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 @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; @@ -38,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -45,8 +47,12 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockMapping; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; @@ -147,6 +153,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture /** Keep binary. */ private final boolean keepBinary; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Registry. * @param keys Keys to lock. @@ -425,7 +433,14 @@ void onResult(UUID nodeId, GridNearLockResponse res) { log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); - MiniFuture mini = miniFuture(res.miniId()); + int miniId; + + if (res instanceof GridNearLockResponseV1) + miniId = (int) ((GridNearLockResponseV1)res).miniId().localId(); + else + miniId = ((GridNearLockResponseV2)res).miniId(); + + MiniFuture mini = miniFuture(miniId); if (mini != null) { assert mini.node().id().equals(nodeId); @@ -457,7 +472,7 @@ else if (log.isDebugEnabled()) * @return Mini future. */ @SuppressWarnings({"ForLoopReplaceableByForEach", "IfMayBeConditional"}) - private MiniFuture miniFuture(IgniteUuid miniId) { + private MiniFuture miniFuture(int miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (futs) { // Avoid iterator creation. @@ -469,7 +484,7 @@ private MiniFuture miniFuture(IgniteUuid miniId) { MiniFuture mini = (MiniFuture)fut; - if (mini.futureId().equals(miniId)) { + if (mini.futureId() == miniId) { if (!mini.isDone()) return mini; else @@ -813,7 +828,7 @@ private synchronized void map0( assert !mappedKeys.isEmpty(); - GridNearLockRequest req = null; + GridNearLockRequestV1 req = null; Collection distributedKeys = new ArrayList<>(mappedKeys.size()); @@ -880,7 +895,7 @@ private synchronized void map0( first = false; } - req = new GridNearLockRequest( + req = new GridNearLockRequestV1( cctx.cacheId(), topVer, cctx.nodeId(), @@ -1016,7 +1031,10 @@ private void proceedMapping0() else { final MiniFuture fut = new MiniFuture(node, mappedKeys); - req.miniId(fut.futureId()); + if (req instanceof GridNearLockRequestV1) + ((GridNearLockRequestV1)req).miniId(new IgniteUuid(GridNearLockRequestV2.DUMMY_UUID, fut.futureId())); + else + ((GridNearLockRequestV2)req).miniId(fut.futureId()); add(fut); // Append new future. @@ -1030,7 +1048,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { assert fut != null; @@ -1045,7 +1063,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { assert fut != null; @@ -1306,7 +1324,7 @@ private class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private int futId = counter.incrementAndGet(); /** Node ID. */ @GridToStringExclude @@ -1334,7 +1352,7 @@ private class MiniFuture extends GridFutureAdapter { /** * @return Future ID. */ - IgniteUuid futureId() { + int futureId() { return futId; } 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 5d4fc01eee3f8..a3e6b78c284e3 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 @@ -25,7 +25,9 @@ import java.util.Map; import java.util.Queue; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterNode; @@ -39,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -75,6 +78,9 @@ */ public final class GridNearLockFuture extends GridCompoundIdentityFuture implements GridCacheMvccFuture { + + private static final UUID DUMMY_UUID = new UUID(0L, 0L); + /** */ private static final long serialVersionUID = 0L; @@ -154,6 +160,8 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture keys, boolean remap, boolean topLocked first = false; } - req = new GridNearLockRequest( - cctx.cacheId(), - topVer, - cctx.nodeId(), - threadId, - futId, - lockVer, - inTx(), - implicitTx(), - implicitSingleTx(), - read, - retval, - isolation(), - isInvalidate(), - timeout, - mappedKeys.size(), - inTx() ? tx.size() : mappedKeys.size(), - inTx() && tx.syncCommit(), - inTx() ? tx.subjectId() : null, - inTx() ? tx.taskNameHash() : 0, - read ? accessTtl : -1L, - skipStore, - keepBinary, - clientFirst, - cctx.deploymentEnabled()); + if (node.version().compareTo(cctx.localNode().version()) >= 0) { + req = new GridNearLockRequestV2( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); + } + else { + req = new GridNearLockRequestV1( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); + } mapping.request(req); } @@ -1131,7 +1174,10 @@ private void proceedMapping0() req.filter(filter, cctx); if (node.isLocal()) { - req.miniId(IgniteUuid.randomUuid()); + if (req instanceof GridNearLockRequestV1) + ((GridNearLockRequestV1)req).miniId(new IgniteUuid(GridNearLockRequestV2.DUMMY_UUID, counter.incrementAndGet())); + else + ((GridNearLockRequestV2)req).miniId(counter.incrementAndGet()); if (log.isDebugEnabled()) log.debug("Before locally locking near request: " + req); @@ -1271,7 +1317,10 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); else { final MiniFuture fut = new MiniFuture(node, mappedKeys); - req.miniId(fut.futureId()); + if (req instanceof GridNearLockRequestV1) + ((GridNearLockRequestV1)req).miniId(new IgniteUuid(GridNearLockRequestV2.DUMMY_UUID, fut.futureId())); + else + ((GridNearLockRequestV2)req).miniId(fut.futureId()); add(fut); // Append new future. @@ -1285,7 +1334,7 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { fut.onResult(ex); @@ -1298,7 +1347,7 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { fut.onResult(ex); @@ -1404,7 +1453,7 @@ private class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int futId = counter.incrementAndGet(); /** Node ID. */ @GridToStringExclude @@ -1432,7 +1481,7 @@ private class MiniFuture extends GridFutureAdapter { /** * @return Future ID. */ - IgniteUuid futureId() { + int futureId() { return futId; } 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 2a6b0a8b373e7..0de4d126757e3 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 @@ -1,596 +1,82 @@ -/* - * 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.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Arrays; -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.GridCacheDeployable; 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; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.transactions.TransactionIsolation; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -/** - * Near cache lock request. - */ -public class GridNearLockRequest extends GridDistributedLockRequest { - /** */ - private static final long serialVersionUID = 0L; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Mini future ID. */ - private IgniteUuid miniId; - - /** Filter. */ - private CacheEntryPredicate[] filter; - - /** Implicit flag. */ - private boolean implicitTx; - - /** Implicit transaction with one key flag. */ - private boolean implicitSingleTx; - - /** Flag is kept for backward compatibility. */ - private boolean onePhaseCommit; - - /** Array of mapped DHT versions for this entry. */ - @GridToStringInclude - private GridCacheVersion[] dhtVers; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Has transforms flag. */ - private boolean hasTransforms; - - /** Sync commit flag. */ - private boolean syncCommit; - - /** TTL for read operation. */ - private long accessTtl; - - /** Flag indicating whether cache operation requires a previous value. */ - private boolean retVal; - - /** {@code True} if first lock request for lock operation sent from client node. */ - private boolean firstClientReq; - - /** - * Empty constructor required for {@link Externalizable}. - */ - public GridNearLockRequest() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param topVer Topology version. - * @param nodeId Node ID. - * @param threadId Thread ID. - * @param futId Future ID. - * @param lockVer Cache version. - * @param isInTx {@code True} if implicit transaction lock. - * @param implicitTx Flag to indicate that transaction is implicit. - * @param implicitSingleTx Implicit-transaction-with-one-key flag. - * @param isRead Indicates whether implicit lock is for read or write operation. - * @param retVal Return value flag. - * @param isolation Transaction isolation. - * @param isInvalidate Invalidation flag. - * @param timeout Lock timeout. - * @param keyCnt Number of keys. - * @param txSize Expected transaction size. - * @param syncCommit Synchronous commit flag. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param accessTtl TTL for read operation. - * @param skipStore Skip store flag. - * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. - * @param addDepInfo Deployment info flag. - */ - public GridNearLockRequest( - int cacheId, - @NotNull AffinityTopologyVersion topVer, - UUID nodeId, - long threadId, - IgniteUuid futId, - GridCacheVersion lockVer, - boolean isInTx, - boolean implicitTx, - boolean implicitSingleTx, - boolean isRead, - boolean retVal, - TransactionIsolation isolation, - boolean isInvalidate, - long timeout, - int keyCnt, - int txSize, - boolean syncCommit, - @Nullable UUID subjId, - int taskNameHash, - long accessTtl, - boolean skipStore, - boolean keepBinary, - boolean firstClientReq, - boolean addDepInfo - - ) { - super( - cacheId, - nodeId, - lockVer, - threadId, - futId, - lockVer, - isInTx, - isRead, - isolation, - isInvalidate, - timeout, - keyCnt, - txSize, - skipStore, - keepBinary, - addDepInfo); - - assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; - - this.topVer = topVer; - this.implicitTx = implicitTx; - this.implicitSingleTx = implicitSingleTx; - this.syncCommit = syncCommit; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.accessTtl = accessTtl; - this.retVal = retVal; - this.firstClientReq = firstClientReq; - - dhtVers = new GridCacheVersion[keyCnt]; - } - - /** - * @return {@code True} if first lock request for lock operation sent from client node. - */ - public boolean firstClientRequest() { - return firstClientReq; - } - - /** - * @return Topology version. - */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } +import java.util.List; +import java.util.UUID; - /** - * @return Subject ID. - */ - public UUID subjectId() { - return subjId; - } +public interface GridNearLockRequest extends Message, GridCacheDeployable, GridCacheVersionable { + boolean firstClientRequest(); - /** - * @return Task name hash.q - */ - public int taskNameHash() { - return taskNameHash; - } + AffinityTopologyVersion topologyVersion(); - /** - * @return Implicit transaction flag. - */ - public boolean implicitTx() { - return implicitTx; - } + UUID subjectId(); - /** - * @return Implicit-transaction-with-one-key flag. - */ - public boolean implicitSingleTx() { - return implicitSingleTx; - } + int taskNameHash(); - /** - * @return Sync commit flag. - */ - public boolean syncCommit() { - return syncCommit; - } + boolean implicitTx(); - /** - * @return Filter. - */ - public CacheEntryPredicate[] filter() { - return filter; - } + boolean implicitSingleTx(); - /** - * @param filter Filter. - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) - throws IgniteCheckedException { - this.filter = filter; - } + boolean syncCommit(); - /** - * @return Mini future ID. - */ - public IgniteUuid miniId() { - return miniId; - } + CacheEntryPredicate[] filter(); - /** - * @param miniId Mini future Id. - */ - public void miniId(IgniteUuid miniId) { - this.miniId = miniId; - } + void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException; - /** - * @param hasTransforms {@code True} if originating transaction has transform entries. - */ - public void hasTransforms(boolean hasTransforms) { - this.hasTransforms = hasTransforms; - } + void hasTransforms(boolean hasTransforms); - /** - * @return {@code True} if originating transaction has transform entries. - */ - public boolean hasTransforms() { - return hasTransforms; - } + boolean hasTransforms(); - /** - * @return Need return value flag. - */ - public boolean needReturnValue() { - return retVal; - } + boolean needReturnValue(); - /** - * Adds a key. - * - * @param key Key. - * @param retVal Flag indicating whether value should be returned. - * @param dhtVer DHT version. - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void addKeyBytes( + void addKeyBytes( KeyCacheObject key, boolean retVal, @Nullable GridCacheVersion dhtVer, GridCacheContext ctx - ) throws IgniteCheckedException { - dhtVers[idx] = dhtVer; - - // Delegate to super. - addKeyBytes(key, retVal, ctx); - } - - /** - * @param idx Index of the key. - * @return DHT version for key at given index. - */ - public GridCacheVersion dhtVersion(int idx) { - return dhtVers[idx]; - } - - /** - * @return TTL for read operation. - */ - public long accessTtl() { - return accessTtl; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (filter != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId); - - for (CacheEntryPredicate p : filter) { - if (p != null) - p.prepareMarshal(cctx); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (filter != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId); - - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - } - - /** {@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 20: - if (!writer.writeLong("accessTtl", accessTtl)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeBoolean("firstClientReq", firstClientReq)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeBoolean("hasTransforms", hasTransforms)) - return false; - - writer.incrementState(); - - case 25: - if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) - return false; - - writer.incrementState(); - - case 26: - if (!writer.writeBoolean("implicitTx", implicitTx)) - return false; - - writer.incrementState(); - - case 27: - if (!writer.writeIgniteUuid("miniId", miniId)) - return false; - - writer.incrementState(); - - case 28: - if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) - return false; - - writer.incrementState(); - - case 29: - if (!writer.writeBoolean("retVal", retVal)) - return false; - - writer.incrementState(); - - case 30: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 31: - if (!writer.writeBoolean("syncCommit", syncCommit)) - return false; - - writer.incrementState(); - - case 32: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 33: - if (!writer.writeMessage("topVer", topVer)) - 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 20: - accessTtl = reader.readLong("accessTtl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 21: - dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - firstClientReq = reader.readBoolean("firstClientReq"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - hasTransforms = reader.readBoolean("hasTransforms"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 25: - implicitSingleTx = reader.readBoolean("implicitSingleTx"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 26: - implicitTx = reader.readBoolean("implicitTx"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 27: - miniId = reader.readIgniteUuid("miniId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 28: - onePhaseCommit = reader.readBoolean("onePhaseCommit"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 29: - retVal = reader.readBoolean("retVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 30: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; + ) throws IgniteCheckedException; - reader.incrementState(); + GridCacheVersion dhtVersion(int idx); - case 31: - syncCommit = reader.readBoolean("syncCommit"); + long accessTtl(); - if (!reader.isLastRead()) - return false; + boolean txRead(); - reader.incrementState(); + long timeout(); - case 32: - taskNameHash = reader.readInt("taskNameHash"); + long threadId(); - if (!reader.isLastRead()) - return false; + boolean skipStore(); - reader.incrementState(); + boolean keepBinary(); - case 33: - topVer = reader.readMessage("topVer"); + boolean inTx(); - if (!reader.isLastRead()) - return false; + List keys(); - reader.incrementState(); + IgniteUuid futureId(); - } + TransactionIsolation isolation(); - return reader.afterMessageRead(GridNearLockRequest.class); - } + boolean isInvalidate(); - /** {@inheritDoc} */ - @Override public byte directType() { - return 51; - } + int txSize(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 34; - } + long messageId(); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearLockRequest.class, this, "filter", Arrays.toString(filter), - "super", super.toString()); - } + boolean returnValue(int idx); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java new file mode 100644 index 0000000000000..14046f56dd03a --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java @@ -0,0 +1,596 @@ +/* + * 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.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Arrays; +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.GridCacheSharedContext; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.transactions.TransactionIsolation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Near cache lock request. + */ +public class GridNearLockRequestV1 extends GridDistributedLockRequest implements GridNearLockRequest { + /** */ + private static final long serialVersionUID = 0L; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Mini future ID. */ + private IgniteUuid miniId; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Implicit flag. */ + private boolean implicitTx; + + /** Implicit transaction with one key flag. */ + private boolean implicitSingleTx; + + /** Flag is kept for backward compatibility. */ + private boolean onePhaseCommit; + + /** Array of mapped DHT versions for this entry. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Has transforms flag. */ + private boolean hasTransforms; + + /** Sync commit flag. */ + private boolean syncCommit; + + /** TTL for read operation. */ + private long accessTtl; + + /** Flag indicating whether cache operation requires a previous value. */ + private boolean retVal; + + /** {@code True} if first lock request for lock operation sent from client node. */ + private boolean firstClientReq; + + /** + * Empty constructor required for {@link Externalizable}. + */ + public GridNearLockRequestV1() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param topVer Topology version. + * @param nodeId Node ID. + * @param threadId Thread ID. + * @param futId Future ID. + * @param lockVer Cache version. + * @param isInTx {@code True} if implicit transaction lock. + * @param implicitTx Flag to indicate that transaction is implicit. + * @param implicitSingleTx Implicit-transaction-with-one-key flag. + * @param isRead Indicates whether implicit lock is for read or write operation. + * @param retVal Return value flag. + * @param isolation Transaction isolation. + * @param isInvalidate Invalidation flag. + * @param timeout Lock timeout. + * @param keyCnt Number of keys. + * @param txSize Expected transaction size. + * @param syncCommit Synchronous commit flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param accessTtl TTL for read operation. + * @param skipStore Skip store flag. + * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. + * @param addDepInfo Deployment info flag. + */ + public GridNearLockRequestV1( + int cacheId, + @NotNull AffinityTopologyVersion topVer, + UUID nodeId, + long threadId, + IgniteUuid futId, + GridCacheVersion lockVer, + boolean isInTx, + boolean implicitTx, + boolean implicitSingleTx, + boolean isRead, + boolean retVal, + TransactionIsolation isolation, + boolean isInvalidate, + long timeout, + int keyCnt, + int txSize, + boolean syncCommit, + @Nullable UUID subjId, + int taskNameHash, + long accessTtl, + boolean skipStore, + boolean keepBinary, + boolean firstClientReq, + boolean addDepInfo + + ) { + super( + cacheId, + nodeId, + lockVer, + threadId, + futId, + lockVer, + isInTx, + isRead, + isolation, + isInvalidate, + timeout, + keyCnt, + txSize, + skipStore, + keepBinary, + addDepInfo); + + assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; + + this.topVer = topVer; + this.implicitTx = implicitTx; + this.implicitSingleTx = implicitSingleTx; + this.syncCommit = syncCommit; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.accessTtl = accessTtl; + this.retVal = retVal; + this.firstClientReq = firstClientReq; + + dhtVers = new GridCacheVersion[keyCnt]; + } + + /** + * @return {@code True} if first lock request for lock operation sent from client node. + */ + @Override public boolean firstClientRequest() { + return firstClientReq; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Subject ID. + */ + @Override public UUID subjectId() { + return subjId; + } + + /** + * @return Task name hash.q + */ + @Override public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Implicit transaction flag. + */ + @Override public boolean implicitTx() { + return implicitTx; + } + + /** + * @return Implicit-transaction-with-one-key flag. + */ + @Override public boolean implicitSingleTx() { + return implicitSingleTx; + } + + /** + * @return Sync commit flag. + */ + @Override public boolean syncCommit() { + return syncCommit; + } + + /** + * @return Filter. + */ + @Override public CacheEntryPredicate[] filter() { + return filter; + } + + /** + * @param filter Filter. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + @Override public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException { + this.filter = filter; + } + + /** + * @return Mini future ID. + */ + public IgniteUuid miniId() { + return miniId; + } + + /** + * @param miniId Mini future Id. + */ + public void miniId(IgniteUuid miniId) { + this.miniId = miniId; + } + + /** + * @param hasTransforms {@code True} if originating transaction has transform entries. + */ + @Override public void hasTransforms(boolean hasTransforms) { + this.hasTransforms = hasTransforms; + } + + /** + * @return {@code True} if originating transaction has transform entries. + */ + @Override public boolean hasTransforms() { + return hasTransforms; + } + + /** + * @return Need return value flag. + */ + @Override public boolean needReturnValue() { + return retVal; + } + + /** + * Adds a key. + * + * @param key Key. + * @param retVal Flag indicating whether value should be returned. + * @param dhtVer DHT version. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + @Override public void addKeyBytes( + KeyCacheObject key, + boolean retVal, + @Nullable GridCacheVersion dhtVer, + GridCacheContext ctx + ) throws IgniteCheckedException { + dhtVers[idx] = dhtVer; + + // Delegate to super. + addKeyBytes(key, retVal, ctx); + } + + /** + * @param idx Index of the key. + * @return DHT version for key at given index. + */ + @Override public GridCacheVersion dhtVersion(int idx) { + return dhtVers[idx]; + } + + /** + * @return TTL for read operation. + */ + @Override public long accessTtl() { + return accessTtl; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.prepareMarshal(cctx); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + } + + /** {@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 20: + if (!writer.writeLong("accessTtl", accessTtl)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeBoolean("firstClientReq", firstClientReq)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeBoolean("hasTransforms", hasTransforms)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) + return false; + + writer.incrementState(); + + case 26: + if (!writer.writeBoolean("implicitTx", implicitTx)) + return false; + + writer.incrementState(); + + case 27: + if (!writer.writeIgniteUuid("miniId", miniId)) + return false; + + writer.incrementState(); + + case 28: + if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) + return false; + + writer.incrementState(); + + case 29: + if (!writer.writeBoolean("retVal", retVal)) + return false; + + writer.incrementState(); + + case 30: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 31: + if (!writer.writeBoolean("syncCommit", syncCommit)) + return false; + + writer.incrementState(); + + case 32: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 33: + if (!writer.writeMessage("topVer", topVer)) + 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 20: + accessTtl = reader.readLong("accessTtl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + firstClientReq = reader.readBoolean("firstClientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + hasTransforms = reader.readBoolean("hasTransforms"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + implicitSingleTx = reader.readBoolean("implicitSingleTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 26: + implicitTx = reader.readBoolean("implicitTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 27: + miniId = reader.readIgniteUuid("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 28: + onePhaseCommit = reader.readBoolean("onePhaseCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 29: + retVal = reader.readBoolean("retVal"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 30: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 31: + syncCommit = reader.readBoolean("syncCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 32: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 33: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockRequestV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 51; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 34; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockRequestV1.class, this, "filter", Arrays.toString(filter), + "super", super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java new file mode 100644 index 0000000000000..f1cd5421ce035 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java @@ -0,0 +1,583 @@ +package org.apache.ignite.internal.processors.cache.distributed.near; + +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.GridCacheSharedContext; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.transactions.TransactionIsolation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.UUID; + +public class GridNearLockRequestV2 extends GridDistributedLockRequest implements GridNearLockRequest { + /** */ + private static final long serialVersionUID = 0L; + + public static final UUID DUMMY_UUID = new UUID(0, 0); + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Mini future ID. */ + private int miniId; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Implicit flag. */ + private boolean implicitTx; + + /** Implicit transaction with one key flag. */ + private boolean implicitSingleTx; + + /** Flag is kept for backward compatibility. */ + private boolean onePhaseCommit; + + /** Array of mapped DHT versions for this entry. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Has transforms flag. */ + private boolean hasTransforms; + + /** Sync commit flag. */ + private boolean syncCommit; + + /** TTL for read operation. */ + private long accessTtl; + + /** Flag indicating whether cache operation requires a previous value. */ + private boolean retVal; + + /** {@code True} if first lock request for lock operation sent from client node. */ + private boolean firstClientReq; + + /** + * Empty constructor required for {@link Externalizable}. + */ + public GridNearLockRequestV2() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param topVer Topology version. + * @param nodeId Node ID. + * @param threadId Thread ID. + * @param futId Future ID. + * @param lockVer Cache version. + * @param isInTx {@code True} if implicit transaction lock. + * @param implicitTx Flag to indicate that transaction is implicit. + * @param implicitSingleTx Implicit-transaction-with-one-key flag. + * @param isRead Indicates whether implicit lock is for read or write operation. + * @param retVal Return value flag. + * @param isolation Transaction isolation. + * @param isInvalidate Invalidation flag. + * @param timeout Lock timeout. + * @param keyCnt Number of keys. + * @param txSize Expected transaction size. + * @param syncCommit Synchronous commit flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param accessTtl TTL for read operation. + * @param skipStore Skip store flag. + * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. + * @param addDepInfo Deployment info flag. + */ + public GridNearLockRequestV2( + int cacheId, + @NotNull AffinityTopologyVersion topVer, + UUID nodeId, + long threadId, + IgniteUuid futId, + GridCacheVersion lockVer, + boolean isInTx, + boolean implicitTx, + boolean implicitSingleTx, + boolean isRead, + boolean retVal, + TransactionIsolation isolation, + boolean isInvalidate, + long timeout, + int keyCnt, + int txSize, + boolean syncCommit, + @Nullable UUID subjId, + int taskNameHash, + long accessTtl, + boolean skipStore, + boolean keepBinary, + boolean firstClientReq, + boolean addDepInfo + + ) { + super( + cacheId, + nodeId, + lockVer, + threadId, + futId, + lockVer, + isInTx, + isRead, + isolation, + isInvalidate, + timeout, + keyCnt, + txSize, + skipStore, + keepBinary, + addDepInfo); + + assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; + + this.topVer = topVer; + this.implicitTx = implicitTx; + this.implicitSingleTx = implicitSingleTx; + this.syncCommit = syncCommit; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.accessTtl = accessTtl; + this.retVal = retVal; + this.firstClientReq = firstClientReq; + + dhtVers = new GridCacheVersion[keyCnt]; + } + + /** + * @return {@code True} if first lock request for lock operation sent from client node. + */ + public boolean firstClientRequest() { + return firstClientReq; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Subject ID. + */ + public UUID subjectId() { + return subjId; + } + + /** + * @return Task name hash.q + */ + public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Implicit transaction flag. + */ + public boolean implicitTx() { + return implicitTx; + } + + /** + * @return Implicit-transaction-with-one-key flag. + */ + public boolean implicitSingleTx() { + return implicitSingleTx; + } + + /** + * @return Sync commit flag. + */ + public boolean syncCommit() { + return syncCommit; + } + + /** + * @return Filter. + */ + public CacheEntryPredicate[] filter() { + return filter; + } + + /** + * @param filter Filter. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException { + this.filter = filter; + } + + /** + * @return Mini future ID. + */ + public int miniId() { + return miniId; + } + + /** + * @param miniId Mini future Id. + */ + public void miniId(int miniId) { + this.miniId = miniId; + } + + public IgniteUuid oldVersionMiniId() { + return new IgniteUuid(DUMMY_UUID, miniId); + } + + /** + * @param hasTransforms {@code True} if originating transaction has transform entries. + */ + public void hasTransforms(boolean hasTransforms) { + this.hasTransforms = hasTransforms; + } + + /** + * @return {@code True} if originating transaction has transform entries. + */ + public boolean hasTransforms() { + return hasTransforms; + } + + /** + * @return Need return value flag. + */ + public boolean needReturnValue() { + return retVal; + } + + /** + * Adds a key. + * + * @param key Key. + * @param retVal Flag indicating whether value should be returned. + * @param dhtVer DHT version. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + public void addKeyBytes( + KeyCacheObject key, + boolean retVal, + @Nullable GridCacheVersion dhtVer, + GridCacheContext ctx + ) throws IgniteCheckedException { + dhtVers[idx] = dhtVer; + + // Delegate to super. + addKeyBytes(key, retVal, ctx); + } + + /** + * @param idx Index of the key. + * @return DHT version for key at given index. + */ + public GridCacheVersion dhtVersion(int idx) { + return dhtVers[idx]; + } + + /** + * @return TTL for read operation. + */ + public long accessTtl() { + return accessTtl; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.prepareMarshal(cctx); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + } + + /** {@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 20: + if (!writer.writeLong("accessTtl", accessTtl)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeBoolean("firstClientReq", firstClientReq)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeBoolean("hasTransforms", hasTransforms)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) + return false; + + writer.incrementState(); + + case 26: + if (!writer.writeBoolean("implicitTx", implicitTx)) + return false; + + writer.incrementState(); + + case 27: + if (!writer.writeInt("miniId", miniId)) + return false; + + writer.incrementState(); + + case 28: + if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) + return false; + + writer.incrementState(); + + case 29: + if (!writer.writeBoolean("retVal", retVal)) + return false; + + writer.incrementState(); + + case 30: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 31: + if (!writer.writeBoolean("syncCommit", syncCommit)) + return false; + + writer.incrementState(); + + case 32: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 33: + if (!writer.writeMessage("topVer", topVer)) + 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 20: + accessTtl = reader.readLong("accessTtl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + firstClientReq = reader.readBoolean("firstClientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + hasTransforms = reader.readBoolean("hasTransforms"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + implicitSingleTx = reader.readBoolean("implicitSingleTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 26: + implicitTx = reader.readBoolean("implicitTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 27: + miniId = reader.readInt("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 28: + onePhaseCommit = reader.readBoolean("onePhaseCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 29: + retVal = reader.readBoolean("retVal"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 30: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 31: + syncCommit = reader.readBoolean("syncCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 32: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 33: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockRequestV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 125; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 34; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockRequestV2.class, this, "filter", Arrays.toString(filter), + "super", super.toString()); + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java index e48a09894164a..dbd53b414a3f5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java @@ -1,330 +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.distributed.near; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Collection; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.GridDirectCollection; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; -/** - * Near cache lock response. - */ -public class GridNearLockResponse extends GridDistributedLockResponse { - /** */ - private static final long serialVersionUID = 0L; - - /** Collection of versions that are pending and less than lock version. */ - @GridToStringInclude - @GridDirectCollection(GridCacheVersion.class) - private Collection pending; - - /** */ - private IgniteUuid miniId; - - /** DHT versions. */ - @GridToStringInclude - private GridCacheVersion[] dhtVers; - - /** DHT candidate versions. */ - @GridToStringInclude - private GridCacheVersion[] mappedVers; - - /** Filter evaluation results for fast-commit transactions. */ - private boolean[] filterRes; - - /** {@code True} if client node should remap lock request. */ - private AffinityTopologyVersion clientRemapVer; - - /** - * Empty constructor (required by {@link Externalizable}). - */ - public GridNearLockResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param lockVer Lock ID. - * @param futId Future ID. - * @param miniId Mini future ID. - * @param filterRes {@code True} if need to allocate array for filter evaluation results. - * @param cnt Count. - * @param err Error. - * @param clientRemapVer {@code True} if client node should remap lock request. - * @param addDepInfo Deployment info. - */ - public GridNearLockResponse( - int cacheId, - GridCacheVersion lockVer, - IgniteUuid futId, - IgniteUuid miniId, - boolean filterRes, - int cnt, - Throwable err, - AffinityTopologyVersion clientRemapVer, - boolean addDepInfo - ) { - super(cacheId, lockVer, futId, cnt, err, addDepInfo); - - assert miniId != null; - - this.miniId = miniId; - this.clientRemapVer = clientRemapVer; - - dhtVers = new GridCacheVersion[cnt]; - mappedVers = new GridCacheVersion[cnt]; - - if (filterRes) - this.filterRes = new boolean[cnt]; - } - - /** - * @return {@code True} if client node should remap lock request. - */ - @Nullable public AffinityTopologyVersion clientRemapVersion() { - return clientRemapVer; - } - - /** - * Gets pending versions that are less than {@link #version()}. - * - * @return Pending versions. - */ - public Collection pending() { - return pending; - } +import java.util.Collection; - /** - * Sets pending versions that are less than {@link #version()}. - * - * @param pending Pending versions. - */ - public void pending(Collection pending) { - this.pending = pending; - } +public interface GridNearLockResponse extends Message, GridCacheDeployable, GridCacheVersionable { + @Nullable AffinityTopologyVersion clientRemapVersion(); - /** - * @return Mini future ID. - */ - public IgniteUuid miniId() { - return miniId; - } + Collection pending(); - /** - * @param idx Index. - * @return DHT version. - */ - public GridCacheVersion dhtVersion(int idx) { - return dhtVers == null ? null : dhtVers[idx]; - } + void pending(Collection pending); - /** - * Returns DHT candidate version for acquired near lock on DHT node. - * - * @param idx Key index. - * @return DHT version. - */ - public GridCacheVersion mappedVersion(int idx) { - return mappedVers == null ? null : mappedVers[idx]; - } + GridCacheVersion dhtVersion(int idx); - /** - * Gets filter evaluation result for fast-commit transaction. - * - * @param idx Result index. - * @return {@code True} if filter passed on primary node, {@code false} otherwise. - */ - public boolean filterResult(int idx) { - assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + GridCacheVersion mappedVersion(int idx); - return filterRes[idx]; - } + boolean filterResult(int idx); - /** - * @param val Value. - * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. - * @param dhtVer DHT version. - * @param mappedVer Mapped version. - * @throws IgniteCheckedException If failed. - */ - public void addValueBytes( + void addValueBytes( @Nullable CacheObject val, boolean filterPassed, @Nullable GridCacheVersion dhtVer, @Nullable GridCacheVersion mappedVer - ) throws IgniteCheckedException { - int idx = valuesSize(); - - dhtVers[idx] = dhtVer; - mappedVers[idx] = mappedVer; - - if (filterRes != null) - filterRes[idx] = filterPassed; - - // Delegate to super. - addValue(val); - } - - /** {@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 10: - if (!writer.writeMessage("clientRemapVer", clientRemapVer)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeBooleanArray("filterRes", filterRes)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeIgniteUuid("miniId", miniId)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) - 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 10: - clientRemapVer = reader.readMessage("clientRemapVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - filterRes = reader.readBooleanArray("filterRes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - miniId = reader.readIgniteUuid("miniId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - pending = reader.readCollection("pending", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); + ) throws IgniteCheckedException; - } + CacheObject value(int idx); - return reader.afterMessageRead(GridNearLockResponse.class); - } + Throwable error(); - /** {@inheritDoc} */ - @Override public byte directType() { - return 52; - } + Collection committedVersions(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 16; - } + Collection rolledbackVersions(); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearLockResponse.class, this, super.toString()); - } + IgniteUuid futureId(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java new file mode 100644 index 0000000000000..98a379fcae96b --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java @@ -0,0 +1,330 @@ +/* + * 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.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Collection; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.jetbrains.annotations.Nullable; + +/** + * Near cache lock response. + */ +public class GridNearLockResponseV1 extends GridDistributedLockResponse implements GridNearLockResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Collection of versions that are pending and less than lock version. */ + @GridToStringInclude + @GridDirectCollection(GridCacheVersion.class) + private Collection pending; + + /** */ + private IgniteUuid miniId; + + /** DHT versions. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** DHT candidate versions. */ + @GridToStringInclude + private GridCacheVersion[] mappedVers; + + /** Filter evaluation results for fast-commit transactions. */ + private boolean[] filterRes; + + /** {@code True} if client node should remap lock request. */ + private AffinityTopologyVersion clientRemapVer; + + /** + * Empty constructor (required by {@link Externalizable}). + */ + public GridNearLockResponseV1() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param lockVer Lock ID. + * @param futId Future ID. + * @param miniId Mini future ID. + * @param filterRes {@code True} if need to allocate array for filter evaluation results. + * @param cnt Count. + * @param err Error. + * @param clientRemapVer {@code True} if client node should remap lock request. + * @param addDepInfo Deployment info. + */ + public GridNearLockResponseV1( + int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + IgniteUuid miniId, + boolean filterRes, + int cnt, + Throwable err, + AffinityTopologyVersion clientRemapVer, + boolean addDepInfo + ) { + super(cacheId, lockVer, futId, cnt, err, addDepInfo); + + assert miniId != null; + + this.miniId = miniId; + this.clientRemapVer = clientRemapVer; + + dhtVers = new GridCacheVersion[cnt]; + mappedVers = new GridCacheVersion[cnt]; + + if (filterRes) + this.filterRes = new boolean[cnt]; + } + + /** + * @return {@code True} if client node should remap lock request. + */ + @Override @Nullable public AffinityTopologyVersion clientRemapVersion() { + return clientRemapVer; + } + + /** + * Gets pending versions that are less than {@link #version()}. + * + * @return Pending versions. + */ + @Override public Collection pending() { + return pending; + } + + /** + * Sets pending versions that are less than {@link #version()}. + * + * @param pending Pending versions. + */ + @Override public void pending(Collection pending) { + this.pending = pending; + } + + /** + * @return Mini future ID. + */ + public IgniteUuid miniId() { + return miniId; + } + + /** + * @param idx Index. + * @return DHT version. + */ + @Override public GridCacheVersion dhtVersion(int idx) { + return dhtVers == null ? null : dhtVers[idx]; + } + + /** + * Returns DHT candidate version for acquired near lock on DHT node. + * + * @param idx Key index. + * @return DHT version. + */ + @Override public GridCacheVersion mappedVersion(int idx) { + return mappedVers == null ? null : mappedVers[idx]; + } + + /** + * Gets filter evaluation result for fast-commit transaction. + * + * @param idx Result index. + * @return {@code True} if filter passed on primary node, {@code false} otherwise. + */ + @Override public boolean filterResult(int idx) { + assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + + return filterRes[idx]; + } + + /** + * @param val Value. + * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. + * @param dhtVer DHT version. + * @param mappedVer Mapped version. + * @throws IgniteCheckedException If failed. + */ + @Override public void addValueBytes( + @Nullable CacheObject val, + boolean filterPassed, + @Nullable GridCacheVersion dhtVer, + @Nullable GridCacheVersion mappedVer + ) throws IgniteCheckedException { + int idx = valuesSize(); + + dhtVers[idx] = dhtVer; + mappedVers[idx] = mappedVer; + + if (filterRes != null) + filterRes[idx] = filterPassed; + + // Delegate to super. + addValue(val); + } + + /** {@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 10: + if (!writer.writeMessage("clientRemapVer", clientRemapVer)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBooleanArray("filterRes", filterRes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeIgniteUuid("miniId", miniId)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) + 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 10: + clientRemapVer = reader.readMessage("clientRemapVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + filterRes = reader.readBooleanArray("filterRes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + miniId = reader.readIgniteUuid("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + pending = reader.readCollection("pending", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockResponseV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 52; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 16; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockResponseV1.class, this, super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java new file mode 100644 index 0000000000000..d2110140a36aa --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java @@ -0,0 +1,310 @@ +package org.apache.ignite.internal.processors.cache.distributed.near; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Collection; + +public class GridNearLockResponseV2 extends GridDistributedLockResponse implements GridNearLockResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Collection of versions that are pending and less than lock version. */ + @GridToStringInclude + @GridDirectCollection(GridCacheVersion.class) + private Collection pending; + + /** */ + private int miniId; + + /** DHT versions. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** DHT candidate versions. */ + @GridToStringInclude + private GridCacheVersion[] mappedVers; + + /** Filter evaluation results for fast-commit transactions. */ + private boolean[] filterRes; + + /** {@code True} if client node should remap lock request. */ + private AffinityTopologyVersion clientRemapVer; + + /** + * Empty constructor (required by {@link Externalizable}). + */ + public GridNearLockResponseV2() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param lockVer Lock ID. + * @param futId Future ID. + * @param miniId Mini future ID. + * @param filterRes {@code True} if need to allocate array for filter evaluation results. + * @param cnt Count. + * @param err Error. + * @param clientRemapVer {@code True} if client node should remap lock request. + * @param addDepInfo Deployment info. + */ + public GridNearLockResponseV2( + int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + int miniId, + boolean filterRes, + int cnt, + Throwable err, + AffinityTopologyVersion clientRemapVer, + boolean addDepInfo + ) { + super(cacheId, lockVer, futId, cnt, err, addDepInfo); + + this.miniId = miniId; + this.clientRemapVer = clientRemapVer; + + dhtVers = new GridCacheVersion[cnt]; + mappedVers = new GridCacheVersion[cnt]; + + if (filterRes) + this.filterRes = new boolean[cnt]; + } + + /** + * @return {@code True} if client node should remap lock request. + */ + @Nullable public AffinityTopologyVersion clientRemapVersion() { + return clientRemapVer; + } + + /** + * Gets pending versions that are less than {@link #version()}. + * + * @return Pending versions. + */ + public Collection pending() { + return pending; + } + + /** + * Sets pending versions that are less than {@link #version()}. + * + * @param pending Pending versions. + */ + public void pending(Collection pending) { + this.pending = pending; + } + + /** + * @return Mini future ID. + */ + public int miniId() { + return miniId; + } + + /** + * @param idx Index. + * @return DHT version. + */ + public GridCacheVersion dhtVersion(int idx) { + return dhtVers == null ? null : dhtVers[idx]; + } + + /** + * Returns DHT candidate version for acquired near lock on DHT node. + * + * @param idx Key index. + * @return DHT version. + */ + public GridCacheVersion mappedVersion(int idx) { + return mappedVers == null ? null : mappedVers[idx]; + } + + /** + * Gets filter evaluation result for fast-commit transaction. + * + * @param idx Result index. + * @return {@code True} if filter passed on primary node, {@code false} otherwise. + */ + public boolean filterResult(int idx) { + assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + + return filterRes[idx]; + } + + /** + * @param val Value. + * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. + * @param dhtVer DHT version. + * @param mappedVer Mapped version. + * @throws IgniteCheckedException If failed. + */ + public void addValueBytes( + @Nullable CacheObject val, + boolean filterPassed, + @Nullable GridCacheVersion dhtVer, + @Nullable GridCacheVersion mappedVer + ) throws IgniteCheckedException { + int idx = valuesSize(); + + dhtVers[idx] = dhtVer; + mappedVers[idx] = mappedVer; + + if (filterRes != null) + filterRes[idx] = filterPassed; + + // Delegate to super. + addValue(val); + } + + /** {@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 10: + if (!writer.writeMessage("clientRemapVer", clientRemapVer)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBooleanArray("filterRes", filterRes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeInt("miniId", miniId)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) + 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 10: + clientRemapVer = reader.readMessage("clientRemapVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + filterRes = reader.readBooleanArray("filterRes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + miniId = reader.readInt("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + pending = reader.readCollection("pending", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockResponseV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 126; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 16; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockResponseV2.class, this, super.toString()); + } +} + 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 a09dec092f624..177546900355c 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 @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -94,8 +95,14 @@ public GridNearTransactionalCache(GridCacheContext ctx) { } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV1 res) { + processLockResponse(nodeId, res); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV2.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV2 res) { processLockResponse(nodeId, res); } }); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java index 13cac81cab558..f45086bb12e58 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java @@ -29,7 +29,7 @@ import org.apache.ignite.IgniteClientDisconnectedException; import org.apache.ignite.IgniteCountDownLatch; import org.apache.ignite.IgniteSemaphore; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.testframework.GridTestUtils; /** @@ -202,7 +202,7 @@ public void testAtomicSeqReconnectInProgress() throws Exception { srvAtomicSeq.batchSize(1); - commSpi.blockMessage(GridNearLockResponse.class); + commSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -362,7 +362,7 @@ public void testAtomicReferenceReconnectInProgress() throws Exception { BlockTpcCommunicationSpi servCommSpi = commSpi(srv); - servCommSpi.blockMessage(GridNearLockResponse.class); + servCommSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -522,7 +522,7 @@ public void testAtomicStampedReconnectInProgress() throws Exception { BlockTpcCommunicationSpi servCommSpi = commSpi(srv); - servCommSpi.blockMessage(GridNearLockResponse.class); + servCommSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -654,7 +654,7 @@ public void testAtomicLongReconnectInProgress() throws Exception { final IgniteAtomicLong srvAtomicLong = srv.atomicLong("atomicLongInProggress", 0, false); - commSpi.blockMessage(GridNearLockResponse.class); + commSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java index ad6c46f284b74..ac4912aa4ccdf 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java @@ -52,7 +52,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse; @@ -557,7 +557,7 @@ public void testReconnectTransactionInProgress2() throws Exception { txInProgressFails(client, ccfg, GridNearTxFinishResponse.class, PESSIMISTIC, 4); - txInProgressFails(client, ccfg, GridNearLockResponse.class, PESSIMISTIC, 5); + txInProgressFails(client, ccfg, GridNearLockResponseV1.class, PESSIMISTIC, 5); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java index f106fecca3361..1089ea1293ccd 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java @@ -26,7 +26,7 @@ import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.TestRecordingCommunicationSpi; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; 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; @@ -66,7 +66,7 @@ public class IgniteCacheNearLockValueSelfTest extends GridCommonAbstractTest { TestRecordingCommunicationSpi commSpi = new TestRecordingCommunicationSpi(); - commSpi.record(GridNearLockRequest.class); + commSpi.record(GridNearLockRequestV1.class); cfg.setCommunicationSpi(commSpi); @@ -94,7 +94,7 @@ public void testDhtVersion() throws Exception { TestRecordingCommunicationSpi comm = (TestRecordingCommunicationSpi)ignite(0).configuration().getCommunicationSpi(); - Collection reqs = (Collection)comm.recordedMessages(); + Collection reqs = (Collection)comm.recordedMessages(); assertEquals(1, reqs.size()); @@ -104,7 +104,7 @@ public void testDhtVersion() throws Exception { assertNotNull(dhtEntry); - GridNearLockRequest req = reqs.iterator().next(); + GridNearLockRequestV1 req = reqs.iterator().next(); assertEquals(dhtEntry.version(), req.dhtVersion(0)); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java index cfa1244ee5273..5c283160bb748 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java @@ -29,7 +29,7 @@ import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiException; @@ -158,7 +158,7 @@ private void countMsg(GridIoMessage msg) { if (origMsg instanceof GridDistributedLockRequest) { distLocks.incrementAndGet(); - if (origMsg instanceof GridNearLockRequest) + if (origMsg instanceof GridNearLockRequestV1) nearLocks.incrementAndGet(); else if (origMsg instanceof GridDhtLockRequest) dhtLocks.incrementAndGet(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index 13f2598c10267..280ab71ee08bc 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -64,7 +64,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.lang.GridAbsPredicate; @@ -599,10 +599,10 @@ private void pessimisticTx(NearCacheConfiguration nearCfg) throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); final IgniteCache cache = ignite2.cache(null); @@ -638,19 +638,19 @@ private void pessimisticTx(NearCacheConfiguration nearCfg) throws Exception { List msgs = spi.recordedMessages(); - assertTrue(((GridNearLockRequest)msgs.get(0)).firstClientRequest()); - assertTrue(((GridNearLockRequest)msgs.get(1)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(0)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(1)).firstClientRequest()); for (int i = 2; i < msgs.size(); i++) - assertFalse(((GridNearLockRequest)msgs.get(i)).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msgs.get(i)).firstClientRequest()); ignite3.close(); for (int i = 0; i < 100; i++) map.put(i, i + 1); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); putFut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -812,9 +812,9 @@ public void testPessimisticTx2() throws Exception { final Integer key1 = keys.get1(); final Integer key2 = keys.get2(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite2.localNode().id()); final IgniteCache cache = ignite3.cache(null); @@ -912,11 +912,11 @@ private void pessimisticTxNoRemap(@Nullable NearCacheConfiguration nearCfg) thro for (int i = 0; i < 100; i++) map.put(i, i); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite2.localNode().id()); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); final IgniteCache cache = ignite3.cache(null); @@ -1155,8 +1155,8 @@ private void lock(NearCacheConfiguration nearCfg) throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -1263,7 +1263,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi(); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); IgniteCache cache = ignite3.cache(null); @@ -1302,7 +1302,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { TestCommunicationSpi spi0 = (TestCommunicationSpi)ignite0.configuration().getCommunicationSpi(); - spi0.record(GridNearLockRequest.class); + spi0.record(GridNearLockRequestV1.class); List keys = primaryKeys(ignite1.cache(null), 3, 0); @@ -1321,7 +1321,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { assertEquals(3, msgs.size()); for (Object msg : msgs) - assertFalse(((GridNearLockRequest)msg).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msg).firstClientRequest()); } /** @@ -1331,10 +1331,10 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { private void checkClientLockMessages(List msgs, int expCnt) { assertEquals(expCnt, msgs.size()); - assertTrue(((GridNearLockRequest)msgs.get(0)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(0)).firstClientRequest()); for (int i = 1; i < msgs.size(); i++) - assertFalse(((GridNearLockRequest)msgs.get(i)).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msgs.get(i)).firstClientRequest()); } /** From 466528329942f009c9e591a16b9453b95830b0cb Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 10:24:01 +0300 Subject: [PATCH 02/34] IGNITE-2532: WIP. Only refactorings for now. --- .../communication/GridIoMessageFactory.java | 6 + .../processors/cache/GridCacheIoManager.java | 17 + .../dht/atomic/GridDhtAtomicCache.java | 42 +- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 12 +- .../GridNearAbstractAtomicUpdateFuture.java | 248 ++++ .../GridNearAtomicSingleUpdateFuture.java | 1264 +++++++++++++++++ .../GridNearAtomicSingleUpdateRequest.java | 1044 ++++++++++++++ .../atomic/GridNearAtomicUpdateFuture.java | 186 +-- .../atomic/GridNearAtomicUpdateRequest.java | 3 +- .../GridNearAtomicUpdateRequestInterface.java | 101 ++ .../distributed/near/GridNearAtomicCache.java | 4 +- 11 files changed, 2725 insertions(+), 202 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.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 3c7f3781622be..25e07b898907c 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 @@ -68,6 +68,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicDeferredUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysRequest; @@ -726,6 +727,11 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; + case -23: + msg = new GridNearAtomicSingleUpdateRequest(); + + break; + // [-3..119] [124] - this // [120..123] - DR // [-4..-22] - SQL 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 b297827007672..57545af70ea97 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 @@ -44,6 +44,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysRequest; @@ -586,6 +587,22 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; + case -23: { + GridNearAtomicSingleUpdateRequest req = (GridNearAtomicSingleUpdateRequest)msg; + + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse( + ctx.cacheId(), + nodeId, + req.futureVersion(), + ctx.deploymentEnabled()); + + res.error(req.classError()); + + sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy()); + } + + break; + default: throw new IgniteCheckedException("Failed to send response to node. Unsupported direct type [message=" + msg + "]", msg.classError()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index f6f57eec2e4d2..cdaa0619b3163 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -139,7 +139,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { Integer.getInteger(IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT, 500); /** Update reply closure. */ - private CI2 updateReplyClos; + private CI2 updateReplyClos; /** Pending */ private ConcurrentMap pendingResponses = new ConcurrentHashMap8<>(); @@ -192,9 +192,9 @@ public GridDhtAtomicCache(GridCacheContext ctx, GridCacheConcurrentMap map } }); - updateReplyClos = new CI2() { + updateReplyClos = new CI2() { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { if (ctx.config().getAtomicWriteOrderMode() == CLOCK) { assert req.writeSynchronizationMode() != FULL_ASYNC : req; @@ -256,6 +256,12 @@ else if (res.error() != null) { } }); + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicSingleUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicSingleUpdateRequest req) { + processNearAtomicUpdateRequest(nodeId, req); + } + }); + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateResponse.class, new CI2() { @Override public void apply(UUID nodeId, GridNearAtomicUpdateResponse res) { processNearAtomicUpdateResponse(nodeId, res); @@ -1304,8 +1310,8 @@ else if (!skipVals && ctx.config().isStatisticsEnabled()) */ public void updateAllAsyncInternal( final UUID nodeId, - final GridNearAtomicUpdateRequest req, - final CI2 completionCb + final GridNearAtomicUpdateRequestInterface req, + final CI2 completionCb ) { IgniteInternalFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); @@ -1329,8 +1335,8 @@ public void updateAllAsyncInternal( */ public void updateAllAsyncInternal0( UUID nodeId, - GridNearAtomicUpdateRequest req, - CI2 completionCb + GridNearAtomicUpdateRequestInterface req, + CI2 completionCb ) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), ctx.deploymentEnabled()); @@ -1552,12 +1558,12 @@ public void updateAllAsyncInternal0( private UpdateBatchResult updateWithBatch( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequest req, + GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -1968,12 +1974,12 @@ private void reloadIfNeeded(final List entries) throws Ignite private UpdateSingleResult updateSingle( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequest req, + GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -2208,8 +2214,8 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable Collection rmvKeys, @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, - final GridNearAtomicUpdateRequest req, + CI2 completionCb, + final GridNearAtomicUpdateRequestInterface req, final GridNearAtomicUpdateResponse res, boolean replicate, UpdateBatchResult batchRes, @@ -2587,7 +2593,7 @@ private void unlockEntries(Collection locked, AffinityTopolog * will return false. * @return {@code True} if filter evaluation succeeded. */ - private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequest req, + private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { try { return ctx.isAllLocked(entry, req.filter()); @@ -2602,7 +2608,7 @@ private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequest /** * @param req Request to remap. */ - private void remapToNewPrimary(GridNearAtomicUpdateRequest req) { + private void remapToNewPrimary(GridNearAtomicUpdateRequestInterface req) { assert req.writeSynchronizationMode() == FULL_ASYNC : req; if (log.isDebugEnabled()) @@ -2681,9 +2687,9 @@ else if (req.operation() == UPDATE) { */ @Nullable private GridDhtAtomicUpdateFuture createDhtFuture( GridCacheVersion writeVer, - GridNearAtomicUpdateRequest updateReq, + GridNearAtomicUpdateRequestInterface updateReq, GridNearAtomicUpdateResponse updateRes, - CI2 completionCb, + CI2 completionCb, boolean force ) { if (!force) { @@ -2714,7 +2720,7 @@ else if (req.operation() == UPDATE) { * @param nodeId Sender node ID. * @param req Near atomic update request. */ - private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequest req) { + private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { if (log.isDebugEnabled()) log.debug("Processing near atomic update request [nodeId=" + nodeId + ", req=" + req + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index e31af19d26641..6891d3b5c9659 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -53,8 +53,7 @@ /** * DHT atomic cache backup update future. */ -public class GridDhtAtomicUpdateFuture extends GridFutureAdapter - implements GridCacheAtomicFuture { +public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture { /** */ private static final long serialVersionUID = 0L; @@ -78,7 +77,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter /** Completion callback. */ @GridToStringExclude - private final CI2 completionCb; + private final CI2 completionCb; /** Mappings. */ @GridToStringInclude @@ -88,7 +87,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter private Map nearReadersEntries; /** Update request. */ - private final GridNearAtomicUpdateRequest updateReq; + private final GridNearAtomicUpdateRequestInterface updateReq; /** Update response. */ private final GridNearAtomicUpdateResponse updateRes; @@ -111,10 +110,9 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, - GridNearAtomicUpdateRequest updateReq, + GridNearAtomicUpdateRequestInterface updateReq, GridNearAtomicUpdateResponse updateRes ) { this.cctx = cctx; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java new file mode 100644 index 0000000000000..60e0c5f720462 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; + +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; +import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; +import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; +import org.apache.ignite.internal.processors.cache.GridCacheOperation; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.future.GridFutureAdapter; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; +import org.jetbrains.annotations.Nullable; + +import javax.cache.expiry.ExpiryPolicy; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + +import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; + +/** + * Base class for near atomic update futures. + */ +public abstract class GridNearAbstractAtomicUpdateFuture extends GridFutureAdapter + implements GridCacheAtomicFuture { + /** Logger reference. */ + protected static final AtomicReference logRef = new AtomicReference<>(); + + /** Logger. */ + protected static IgniteLogger log; + + /** Optional arguments for entry processor. */ + protected Object[] invokeArgs; + + /** Cache context. */ + protected final GridCacheContext cctx; + + /** Cache. */ + protected final GridDhtAtomicCache cache; + + /** Update operation. */ + protected final GridCacheOperation op; + + /** Return value require flag. */ + protected final boolean retval; + + /** Expiry policy. */ + protected final ExpiryPolicy expiryPlc; + + /** Optional filter. */ + protected final CacheEntryPredicate[] filter; + + /** Write synchronization mode. */ + protected final CacheWriteSynchronizationMode syncMode; + + /** Raw return value flag. */ + protected final boolean rawRetval; + + /** Fast map flag. */ + protected final boolean fastMap; + + /** Near cache flag. */ + protected final boolean nearEnabled; + + /** Subject ID. */ + protected final UUID subjId; + + /** Task name hash. */ + protected final int taskNameHash; + + /** Skip store flag. */ + protected final boolean skipStore; + + /** */ + protected final boolean keepBinary; + + /** Wait for topology future flag. */ + protected final boolean waitTopFut; + + /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ + protected boolean topLocked; + + /** Remap count. */ + protected int remapCnt; + + /** + * @param cctx Cache context. + * @param cache Cache instance. + * @param syncMode Write synchronization mode. + * @param op Update operation. + * @param invokeArgs Optional arguments for entry processor. + * @param retval Return value require flag. + * @param rawRetval {@code True} if should return {@code GridCacheReturn} as future result. + * @param expiryPlc Expiry policy explicitly specified for cache operation. + * @param filter Entry filter. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param skipStore Skip store flag. + * @param keepBinary Keep binary flag. + * @param remapCnt Maximum number of retries. + * @param waitTopFut If {@code false} does not wait for affinity change future. + */ + public GridNearAbstractAtomicUpdateFuture( + GridCacheContext cctx, + GridDhtAtomicCache cache, + CacheWriteSynchronizationMode syncMode, + GridCacheOperation op, + @Nullable Object[] invokeArgs, + final boolean retval, + final boolean rawRetval, + @Nullable ExpiryPolicy expiryPlc, + final CacheEntryPredicate[] filter, + UUID subjId, + int taskNameHash, + boolean skipStore, + boolean keepBinary, + int remapCnt, + boolean waitTopFut + ) { + this.rawRetval = rawRetval; + + assert subjId != null; + + this.cctx = cctx; + this.cache = cache; + this.syncMode = syncMode; + this.op = op; + this.invokeArgs = invokeArgs; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.waitTopFut = waitTopFut; + + if (log == null) + log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); + + fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && + cctx.config().getAtomicWriteOrderMode() == CLOCK && + !(cctx.writeThrough() && cctx.config().getInterceptor() != null); + + nearEnabled = CU.isNearEnabled(cctx); + + if (!waitTopFut) + remapCnt = 1; + + this.remapCnt = remapCnt; + } + + /** {@inheritDoc} */ + @Override public IgniteUuid futureId() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean trackable() { + return true; + } + + /** {@inheritDoc} */ + @Override public void markNotTrackable() { + // No-op. + } + + /** + * @return {@code True} if this future should block partition map exchange. + */ + protected boolean waitForPartitionExchange() { + // Wait fast-map near atomic update futures in CLOCK mode. + return fastMap; + } + + /** + * Updates near cache. + * + * @param req Update request. + * @param res Update response. + */ + protected void updateNear(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { + assert nearEnabled; + + if (res.remapKeys() != null || !req.hasPrimary()) + return; + + GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); + + near.processNearAtomicUpdateResponse(req, res); + } + + /** + * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. + */ + protected boolean storeFuture() { + return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; + } + + /** + * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near + * node and send updates in parallel to all participating nodes. + * + * @param key Key to map. + * @param topVer Topology version to map. + * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. + * @return Collection of nodes to which key is mapped. + */ + protected Collection mapKey(KeyCacheObject key, AffinityTopologyVersion topVer, boolean fastMap + ) { + GridCacheAffinityManager affMgr = cctx.affinity(); + + // If we can send updates in parallel - do it. + return fastMap ? + cctx.topology().nodes(affMgr.partition(key), topVer) : + Collections.singletonList(affMgr.primary(key, topVer)); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java new file mode 100644 index 0000000000000..d633e479bc0ef --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java @@ -0,0 +1,1264 @@ +/* + * 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.atomic; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.cluster.ClusterNode; +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.CacheEntryPredicate; +import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException; +import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; +import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; +import org.apache.ignite.internal.processors.cache.GridCacheOperation; +import org.apache.ignite.internal.processors.cache.GridCacheReturn; +import org.apache.ignite.internal.processors.cache.GridCacheTryPutFailedException; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; +import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.future.GridFinishedFuture; +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.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.IgniteUuid; +import org.jetbrains.annotations.Nullable; + +import javax.cache.expiry.ExpiryPolicy; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + +import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; + +/** + * DHT atomic cache single near update future. + */ +public class GridNearAtomicSingleUpdateFuture extends GridFutureAdapter + implements GridCacheAtomicFuture{ + /** Logger reference. */ + private static final AtomicReference logRef = new AtomicReference<>(); + + /** Logger. */ + protected static IgniteLogger log; + + /** Cache context. */ + private final GridCacheContext cctx; + + /** Cache. */ + private GridDhtAtomicCache cache; + + /** Update operation. */ + private final GridCacheOperation op; + + /** Keys */ + private Collection keys; + + /** Values. */ + @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + private Collection vals; + + /** Optional arguments for entry processor. */ + private Object[] invokeArgs; + + /** Conflict put values. */ + @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + private Collection conflictPutVals; + + /** Conflict remove values. */ + @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + private Collection conflictRmvVals; + + /** Return value require flag. */ + private final boolean retval; + + /** Expiry policy. */ + private final ExpiryPolicy expiryPlc; + + /** Optional filter. */ + private final CacheEntryPredicate[] filter; + + /** Write synchronization mode. */ + private final CacheWriteSynchronizationMode syncMode; + + /** Raw return value flag. */ + private final boolean rawRetval; + + /** Fast map flag. */ + private final boolean fastMap; + + /** Near cache flag. */ + private final boolean nearEnabled; + + /** Subject ID. */ + private final UUID subjId; + + /** Task name hash. */ + private final int taskNameHash; + + /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ + private boolean topLocked; + + /** Skip store flag. */ + private final boolean skipStore; + + /** */ + private final boolean keepBinary; + + /** Wait for topology future flag. */ + private final boolean waitTopFut; + + /** Remap count. */ + private int remapCnt; + + /** State. */ + private final UpdateState state; + + /** + * @param cctx Cache context. + * @param cache Cache instance. + * @param syncMode Write synchronization mode. + * @param op Update operation. + * @param keys Keys to update. + * @param vals Values or transform closure. + * @param invokeArgs Optional arguments for entry processor. + * @param conflictPutVals Conflict put values (optional). + * @param conflictRmvVals Conflict remove values (optional). + * @param retval Return value require flag. + * @param rawRetval {@code True} if should return {@code GridCacheReturn} as future result. + * @param expiryPlc Expiry policy explicitly specified for cache operation. + * @param filter Entry filter. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param skipStore Skip store flag. + * @param keepBinary Keep binary flag. + * @param remapCnt Maximum number of retries. + * @param waitTopFut If {@code false} does not wait for affinity change future. + */ + public GridNearAtomicSingleUpdateFuture( + GridCacheContext cctx, + GridDhtAtomicCache cache, + CacheWriteSynchronizationMode syncMode, + GridCacheOperation op, + Collection keys, + @Nullable Collection vals, + @Nullable Object[] invokeArgs, + @Nullable Collection conflictPutVals, + @Nullable Collection conflictRmvVals, + final boolean retval, + final boolean rawRetval, + @Nullable ExpiryPolicy expiryPlc, + final CacheEntryPredicate[] filter, + UUID subjId, + int taskNameHash, + boolean skipStore, + boolean keepBinary, + int remapCnt, + boolean waitTopFut + ) { + this.rawRetval = rawRetval; + + assert vals == null || vals.size() == keys.size(); + assert conflictPutVals == null || conflictPutVals.size() == keys.size(); + assert conflictRmvVals == null || conflictRmvVals.size() == keys.size(); + assert subjId != null; + + this.cctx = cctx; + this.cache = cache; + this.syncMode = syncMode; + this.op = op; + this.keys = keys; + this.vals = vals; + this.invokeArgs = invokeArgs; + this.conflictPutVals = conflictPutVals; + this.conflictRmvVals = conflictRmvVals; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.waitTopFut = waitTopFut; + + if (log == null) + log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); + + fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && + cctx.config().getAtomicWriteOrderMode() == CLOCK && + !(cctx.writeThrough() && cctx.config().getInterceptor() != null); + + nearEnabled = CU.isNearEnabled(cctx); + + if (!waitTopFut) + remapCnt = 1; + + this.remapCnt = remapCnt; + + state = new UpdateState(); + } + + /** {@inheritDoc} */ + @Override public IgniteUuid futureId() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public GridCacheVersion version() { + return state.futureVersion(); + } + + /** + * @return {@code True} if this future should block partition map exchange. + */ + private boolean waitForPartitionExchange() { + // Wait fast-map near atomic update futures in CLOCK mode. + return fastMap; + } + + /** {@inheritDoc} */ + @Override public Collection keys() { + return keys; + } + + /** {@inheritDoc} */ + @Override public boolean onNodeLeft(UUID nodeId) { + state.onNodeLeft(nodeId); + + return false; + } + + /** {@inheritDoc} */ + @Override public boolean trackable() { + return true; + } + + /** {@inheritDoc} */ + @Override public void markNotTrackable() { + // No-op. + } + + /** + * Performs future mapping. + */ + public void map() { + AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); + + if (topVer == null) + mapOnTopology(); + else { + topLocked = true; + + // Cannot remap. + remapCnt = 1; + + state.map(topVer, null); + } + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer) { + if (waitForPartitionExchange()) { + GridFutureAdapter fut = state.completeFuture(topVer); + + if (fut != null && isDone()) { + fut.onDone(); + + return null; + } + + return fut; + } + + return null; + } + + /** {@inheritDoc} */ + @SuppressWarnings("ConstantConditions") + @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) { + assert res == null || res instanceof GridCacheReturn; + + GridCacheReturn ret = (GridCacheReturn)res; + + Object retval = + res == null ? null : rawRetval ? ret : (this.retval || op == TRANSFORM) ? + cctx.unwrapBinaryIfNeeded(ret.value(), keepBinary) : ret.success(); + + if (op == TRANSFORM && retval == null) + retval = Collections.emptyMap(); + + if (super.onDone(retval, err)) { + GridCacheVersion futVer = state.onFutureDone(); + + if (futVer != null) + cctx.mvcc().removeAtomicFuture(futVer); + + return true; + } + + return false; + } + + /** + * Response callback. + * + * @param nodeId Node ID. + * @param res Update response. + */ + public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { + state.onResult(nodeId, res, false); + } + + /** + * Updates near cache. + * + * @param req Update request. + * @param res Update response. + */ + private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + assert nearEnabled; + + if (res.remapKeys() != null || !req.hasPrimary()) + return; + + GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); + + near.processNearAtomicUpdateResponse(req, res); + } + + /** + * Maps future on ready topology. + */ + private void mapOnTopology() { + cache.topology().readLock(); + + AffinityTopologyVersion topVer = null; + + try { + if (cache.topology().stopping()) { + onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " + + cache.name())); + + return; + } + + GridDhtTopologyFuture fut = cache.topology().topologyVersionFuture(); + + if (fut.isDone()) { + Throwable err = fut.validateCache(cctx); + + if (err != null) { + onDone(err); + + return; + } + + topVer = fut.topologyVersion(); + } + else { + if (waitTopFut) { + assert !topLocked : this; + + fut.listen(new CI1>() { + @Override public void apply(IgniteInternalFuture t) { + cctx.kernalContext().closure().runLocalSafe(new Runnable() { + @Override public void run() { + mapOnTopology(); + } + }); + } + }); + } + else + onDone(new GridCacheTryPutFailedException()); + + return; + } + } + finally { + cache.topology().readUnlock(); + } + + state.map(topVer, null); + } + + /** + * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. + */ + private boolean storeFuture() { + return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; + } + + /** + * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near + * node and send updates in parallel to all participating nodes. + * + * @param key Key to map. + * @param topVer Topology version to map. + * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. + * @return Collection of nodes to which key is mapped. + */ + private Collection mapKey( + KeyCacheObject key, + AffinityTopologyVersion topVer, + boolean fastMap + ) { + GridCacheAffinityManager affMgr = cctx.affinity(); + + // If we can send updates in parallel - do it. + return fastMap ? + cctx.topology().nodes(affMgr.partition(key), topVer) : + Collections.singletonList(affMgr.primary(key, topVer)); + } + + /** + * Maps future to single node. + * + * @param nodeId Node ID. + * @param req Request. + */ + private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { + if (cctx.localNodeId().equals(nodeId)) { + cache.updateAllAsyncInternal(nodeId, req, + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + onResult(res.nodeId(), res); + } + }); + } + else { + try { + if (log.isDebugEnabled()) + log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); + + cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); + + if (syncMode == FULL_ASYNC) + onDone(new GridCacheReturn(cctx, true, true, null, true)); + } + catch (IgniteCheckedException e) { + state.onSendError(req, e); + } + } + } + + /** + * Sends messages to remote nodes and updates local cache. + * + * @param mappings Mappings to send. + */ + private void doUpdate(Map mappings) { + UUID locNodeId = cctx.localNodeId(); + + GridNearAtomicUpdateRequest locUpdate = null; + + // Send messages to remote nodes first, then run local update. + for (GridNearAtomicUpdateRequest req : mappings.values()) { + if (locNodeId.equals(req.nodeId())) { + assert locUpdate == null : "Cannot have more than one local mapping [locUpdate=" + locUpdate + + ", req=" + req + ']'; + + locUpdate = req; + } + else { + try { + if (log.isDebugEnabled()) + log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); + + cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); + } + catch (IgniteCheckedException e) { + state.onSendError(req, e); + } + } + } + + if (locUpdate != null) { + cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + onResult(res.nodeId(), res); + } + }); + } + + if (syncMode == FULL_ASYNC) + onDone(new GridCacheReturn(cctx, true, true, null, true)); + } + + /** + * + */ + private class UpdateState { + /** Current topology version. */ + private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; + + /** */ + private GridCacheVersion updVer; + + /** Topology version when got mapping error. */ + private AffinityTopologyVersion mapErrTopVer; + + /** Mappings if operations is mapped to more than one node. */ + @GridToStringInclude + private Map mappings; + + /** */ + private int resCnt; + + /** Error. */ + private CachePartialUpdateCheckedException err; + + /** Future ID. */ + private GridCacheVersion futVer; + + /** Completion future for a particular topology version. */ + private GridFutureAdapter topCompleteFut; + + /** Keys to remap. */ + private Collection remapKeys; + + /** Not null is operation is mapped to single node. */ + private GridNearAtomicUpdateRequest singleReq; + + /** Operation result. */ + private GridCacheReturn opRes; + + /** + * @return Future version. + */ + @Nullable synchronized GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @param nodeId Left node ID. + */ + void onNodeLeft(UUID nodeId) { + GridNearAtomicUpdateResponse res = null; + + synchronized (this) { + GridNearAtomicUpdateRequest req; + + if (singleReq != null) + req = singleReq.nodeId().equals(nodeId) ? singleReq : null; + else + req = mappings != null ? mappings.get(nodeId) : null; + + if (req != null && req.response() == null) { + res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); + + ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + + "before response is received: " + nodeId); + + e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); + + res.addFailedKeys(req.keys(), e); + } + } + + if (res != null) + onResult(nodeId, res, true); + } + + /** + * @param nodeId Node ID. + * @param res Response. + * @param nodeErr {@code True} if response was created on node failure. + */ + @SuppressWarnings("unchecked") + void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { + GridNearAtomicUpdateRequest req; + + AffinityTopologyVersion remapTopVer = null; + + GridCacheReturn opRes0 = null; + CachePartialUpdateCheckedException err0 = null; + + boolean rcvAll; + + GridFutureAdapter fut0 = null; + + synchronized (this) { + if (!res.futureVersion().equals(futVer)) + return; + + if (singleReq != null) { + if (!singleReq.nodeId().equals(nodeId)) + return; + + req = singleReq; + + singleReq = null; + + rcvAll = true; + } + else { + req = mappings != null ? mappings.get(nodeId) : null; + + if (req != null && req.onResponse(res)) { + resCnt++; + + rcvAll = mappings.size() == resCnt; + } + else + return; + } + + assert req != null && req.topologyVersion().equals(topVer) : req; + + if (res.remapKeys() != null) { + assert !fastMap || cctx.kernalContext().clientNode(); + + if (remapKeys == null) + remapKeys = U.newHashSet(res.remapKeys().size()); + + remapKeys.addAll(res.remapKeys()); + + if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) + mapErrTopVer = req.topologyVersion(); + } + else if (res.error() != null) { + if (res.failedKeys() != null) + addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); + } + else { + if (!req.fastMap() || req.hasPrimary()) { + GridCacheReturn ret = res.returnValue(); + + if (op == TRANSFORM) { + if (ret != null) + addInvokeResults(ret); + } + else + opRes = ret; + } + } + + if (rcvAll) { + if (remapKeys != null) { + assert mapErrTopVer != null; + + remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); + } + else { + if (err != null && + X.hasCause(err, CachePartialUpdateCheckedException.class) && + X.hasCause(err, ClusterTopologyCheckedException.class) && + storeFuture() && + --remapCnt > 0) { + ClusterTopologyCheckedException topErr = + X.cause(err, ClusterTopologyCheckedException.class); + + if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { + CachePartialUpdateCheckedException cause = + X.cause(err, CachePartialUpdateCheckedException.class); + + assert cause != null && cause.topologyVersion() != null : err; + + remapTopVer = + new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); + + err = null; + + Collection failedKeys = cause.failedKeys(); + + remapKeys = new ArrayList<>(failedKeys.size()); + + for (Object key : failedKeys) + remapKeys.add(cctx.toCacheKeyObject(key)); + + updVer = null; + } + } + } + + if (remapTopVer == null) { + err0 = err; + opRes0 = opRes; + } + else { + fut0 = topCompleteFut; + + topCompleteFut = null; + + cctx.mvcc().removeAtomicFuture(futVer); + + futVer = null; + topVer = AffinityTopologyVersion.ZERO; + } + } + } + + if (res.error() != null && res.failedKeys() == null) { + onDone(res.error()); + + return; + } + + if (rcvAll && nearEnabled) { + if (mappings != null) { + for (GridNearAtomicUpdateRequest req0 : mappings.values()) { + GridNearAtomicUpdateResponse res0 = req0.response(); + + assert res0 != null : req0; + + updateNear(req0, res0); + } + } + else if (!nodeErr) + updateNear(req, res); + } + + if (remapTopVer != null) { + if (fut0 != null) + fut0.onDone(); + + if (!waitTopFut) { + onDone(new GridCacheTryPutFailedException()); + + return; + } + + if (topLocked) { + assert !F.isEmpty(remapKeys) : remapKeys; + + CachePartialUpdateCheckedException e = + new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + + ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( + "Failed to update keys, topology changed while execute atomic update inside transaction."); + + cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); + + e.add(remapKeys, cause); + + onDone(e); + + return; + } + + IgniteInternalFuture fut = + cctx.shared().exchange().affinityReadyFuture(remapTopVer); + + if (fut == null) + fut = new GridFinishedFuture<>(remapTopVer); + + fut.listen(new CI1>() { + @Override public void apply(final IgniteInternalFuture fut) { + cctx.kernalContext().closure().runLocalSafe(new Runnable() { + @Override public void run() { + try { + AffinityTopologyVersion topVer = fut.get(); + + map(topVer, remapKeys); + } + catch (IgniteCheckedException e) { + onDone(e); + } + } + }); + } + }); + + return; + } + + if (rcvAll) + onDone(opRes0, err0); + } + + /** + * @param req Request. + * @param e Error. + */ + void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { + synchronized (this) { + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); + + res.addFailedKeys(req.keys(), e); + + onResult(req.nodeId(), res, true); + } + } + + /** + * @param topVer Topology version. + * @param remapKeys Keys to remap. + */ + void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { + Collection topNodes = CU.affinityNodes(cctx, topVer); + + if (F.isEmpty(topNodes)) { + onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid).")); + + return; + } + + Exception err = null; + GridNearAtomicUpdateRequest singleReq0 = null; + Map mappings0 = null; + + int size = keys.size(); + + GridCacheVersion futVer = cctx.versions().next(topVer); + + GridCacheVersion updVer; + + // Assign version on near node in CLOCK ordering mode even if fastMap is false. + if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { + updVer = this.updVer; + + if (updVer == null) { + updVer = cctx.versions().next(topVer); + + if (log.isDebugEnabled()) + log.debug("Assigned fast-map version for update on near node: " + updVer); + } + } + else + updVer = null; + + try { + if (size == 1 && !fastMap) { + assert remapKeys == null || remapKeys.size() == 1; + + singleReq0 = mapSingleUpdate(topVer, futVer, updVer); + } + else { + Map pendingMappings = mapUpdate(topNodes, + topVer, + futVer, + updVer, + remapKeys); + + if (pendingMappings.size() == 1) + singleReq0 = F.firstValue(pendingMappings); + else { + if (syncMode == PRIMARY_SYNC) { + mappings0 = U.newHashMap(pendingMappings.size()); + + for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { + if (req.hasPrimary()) + mappings0.put(req.nodeId(), req); + } + } + else + mappings0 = pendingMappings; + + assert !mappings0.isEmpty() || size == 0 : GridNearAtomicSingleUpdateFuture.this; + } + } + + synchronized (this) { + assert this.futVer == null : this; + assert this.topVer == AffinityTopologyVersion.ZERO : this; + + this.topVer = topVer; + this.updVer = updVer; + this.futVer = futVer; + + resCnt = 0; + + singleReq = singleReq0; + mappings = mappings0; + + this.remapKeys = null; + } + } + catch (Exception e) { + err = e; + } + + if (err != null) { + onDone(err); + + return; + } + + if (storeFuture()) { + if (!cctx.mvcc().addAtomicFuture(futVer, GridNearAtomicSingleUpdateFuture.this)) { + assert isDone() : GridNearAtomicSingleUpdateFuture.this; + + return; + } + } + + // Optimize mapping for single key. + if (singleReq0 != null) + mapSingle(singleReq0.nodeId(), singleReq0); + else { + assert mappings0 != null; + + if (size == 0) + onDone(new GridCacheReturn(cctx, true, true, null, true)); + else + doUpdate(mappings0); + } + } + + /** + * @param topVer Topology version. + * @return Future. + */ + @Nullable synchronized GridFutureAdapter completeFuture(AffinityTopologyVersion topVer) { + if (this.topVer == AffinityTopologyVersion.ZERO) + return null; + + if (this.topVer.compareTo(topVer) < 0) { + if (topCompleteFut == null) + topCompleteFut = new GridFutureAdapter<>(); + + return topCompleteFut; + } + + return null; + } + + /** + * @return Future version. + */ + GridCacheVersion onFutureDone() { + GridCacheVersion ver0; + + GridFutureAdapter fut0; + + synchronized (this) { + fut0 = topCompleteFut; + + topCompleteFut = null; + + ver0 = futVer; + + futVer = null; + } + + if (fut0 != null) + fut0.onDone(); + + return ver0; + } + + /** + * @param topNodes Cache nodes. + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @param remapKeys Keys to remap. + * @return Mapping. + * @throws Exception If failed. + */ + private Map mapUpdate(Collection topNodes, + AffinityTopologyVersion topVer, + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer, + @Nullable Collection remapKeys) throws Exception { + Iterator it = null; + + if (vals != null) + it = vals.iterator(); + + Iterator conflictPutValsIt = null; + + if (conflictPutVals != null) + conflictPutValsIt = conflictPutVals.iterator(); + + Iterator conflictRmvValsIt = null; + + if (conflictRmvVals != null) + conflictRmvValsIt = conflictRmvVals.iterator(); + + Map pendingMappings = U.newHashMap(topNodes.size()); + + // Create mappings first, then send messages. + for (Object key : keys) { + if (key == null) + throw new NullPointerException("Null key."); + + Object val; + GridCacheVersion conflictVer; + long conflictTtl; + long conflictExpireTime; + + if (vals != null) { + val = it.next(); + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + + if (val == null) + throw new NullPointerException("Null value."); + } + else if (conflictPutVals != null) { + GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); + + val = conflictPutVal.valueEx(); + conflictVer = conflictPutVal.version(); + conflictTtl = conflictPutVal.ttl(); + conflictExpireTime = conflictPutVal.expireTime(); + } + else if (conflictRmvVals != null) { + val = null; + conflictVer = conflictRmvValsIt.next(); + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + else { + val = null; + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + + if (val == null && op != GridCacheOperation.DELETE) + continue; + + KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + + if (remapKeys != null && !remapKeys.contains(cacheKey)) + continue; + + if (op != TRANSFORM) + val = cctx.toCacheObject(val); + + Collection affNodes = mapKey(cacheKey, topVer, fastMap); + + if (affNodes.isEmpty()) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); + + int i = 0; + + for (ClusterNode affNode : affNodes) { + if (affNode == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); + + UUID nodeId = affNode.id(); + + GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); + + if (mapped == null) { + mapped = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + keys.size()); + + pendingMappings.put(nodeId, mapped); + } + + mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); + + i++; + } + } + + return pendingMappings; + } + + /** + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @return Request. + * @throws Exception If failed. + */ + private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer) throws Exception { + Object key = F.first(keys); + + Object val; + GridCacheVersion conflictVer; + long conflictTtl; + long conflictExpireTime; + + if (vals != null) { + // Regular PUT. + val = F.first(vals); + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + else if (conflictPutVals != null) { + // Conflict PUT. + GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); + + val = conflictPutVal.valueEx(); + conflictVer = conflictPutVal.version(); + conflictTtl = conflictPutVal.ttl(); + conflictExpireTime = conflictPutVal.expireTime(); + } + else if (conflictRmvVals != null) { + // Conflict REMOVE. + val = null; + conflictVer = F.first(conflictRmvVals); + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + else { + // Regular REMOVE. + val = null; + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + + // We still can get here if user pass map with single element. + if (key == null) + throw new NullPointerException("Null key."); + + if (val == null && op != GridCacheOperation.DELETE) + throw new NullPointerException("Null value."); + + KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + + if (op != TRANSFORM) + val = cctx.toCacheObject(val); + + ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); + + if (primary == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid)."); + + GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; + } + + /** + * @param ret Result from single node. + */ + @SuppressWarnings("unchecked") + private void addInvokeResults(GridCacheReturn ret) { + assert op == TRANSFORM : op; + assert ret.value() == null || ret.value() instanceof Map : ret.value(); + + if (ret.value() != null) { + if (opRes != null) + opRes.mergeEntryProcessResults(ret); + else + opRes = ret; + } + } + + /** + * @param failedKeys Failed keys. + * @param topVer Topology version for failed update. + * @param err Error cause. + */ + private void addFailedKeys(Collection failedKeys, + AffinityTopologyVersion topVer, + Throwable err) { + CachePartialUpdateCheckedException err0 = this.err; + + if (err0 == null) + err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + + Collection keys = new ArrayList<>(failedKeys.size()); + + for (KeyCacheObject key : failedKeys) + keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); + + err0.add(keys, err, topVer); + } + + /** {@inheritDoc} */ + @Override public synchronized String toString() { + return S.toString(UpdateState.class, this); + } + } + + /** {@inheritDoc} */ + public String toString() { + return S.toString(GridNearAtomicSingleUpdateFuture.class, this, super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java new file mode 100644 index 0000000000000..5de9884e00e48 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -0,0 +1,1044 @@ +/* + * 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.atomic; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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.IgniteExternalizableExpiryPolicy; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.processor.EntryProcessor; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; + +/** + * Lite DHT cache update request sent from near node to primary node. + */ +public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage + implements GridNearAtomicUpdateRequestInterface, GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Target node ID. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Fast map flag. */ + private boolean fastMap; + + /** Update version. Set to non-null if fastMap is {@code true}. */ + private GridCacheVersion updateVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ + private boolean topLocked; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Update operation. */ + private GridCacheOperation op; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** Conflict TTLs. */ + private GridLongList conflictTtls; + + /** Conflict expire times. */ + private GridLongList conflictExpireTimes; + + /** Return value flag. */ + private boolean retval; + + /** Expiry policy. */ + @GridDirectTransient + private ExpiryPolicy expiryPlc; + + /** Expiry policy bytes. */ + private byte[] expiryPlcBytes; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Flag indicating whether request contains primary keys. */ + private boolean hasPrimary; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Skip write-through to a persistent storage. */ + private boolean skipStore; + + /** */ + private boolean clientReq; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** */ + @GridDirectTransient + private GridNearAtomicUpdateResponse res; + + /** Maximum possible size of inner collections. */ + @GridDirectTransient + private int initSize; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridNearAtomicSingleUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param fastMap Fast map scheme flag. + * @param updateVer Update version set if fast map is performed. + * @param topVer Topology version. + * @param topLocked Topology locked flag. + * @param syncMode Synchronization mode. + * @param op Cache update operation. + * @param retval Return value required flag. + * @param expiryPlc Expiry policy. + * @param invokeArgs Optional arguments for entry processor. + * @param filter Optional filter for atomic check. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param skipStore Skip write-through to a persistent storage. + * @param keepBinary Keep binary flag. + * @param clientReq Client node request flag. + * @param addDepInfo Deployment info flag. + * @param maxEntryCnt Maximum entries count. + */ + public GridNearAtomicSingleUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + boolean fastMap, + @Nullable GridCacheVersion updateVer, + @NotNull AffinityTopologyVersion topVer, + boolean topLocked, + CacheWriteSynchronizationMode syncMode, + GridCacheOperation op, + boolean retval, + @Nullable ExpiryPolicy expiryPlc, + @Nullable Object[] invokeArgs, + @Nullable CacheEntryPredicate[] filter, + @Nullable UUID subjId, + int taskNameHash, + boolean skipStore, + boolean keepBinary, + boolean clientReq, + boolean addDepInfo, + int maxEntryCnt + ) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.fastMap = fastMap; + this.updateVer = updateVer; + + this.topVer = topVer; + this.topLocked = topLocked; + this.syncMode = syncMode; + this.op = op; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.invokeArgs = invokeArgs; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.clientReq = clientReq; + this.addDepInfo = addDepInfo; + + // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries + // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys + // participate in request. As such, we know upper bound of all collections in request. If this bound is lower + // than 10, we use it. + initSize = Math.min(maxEntryCnt, 10); + + keys = new ArrayList<>(initSize); + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Mapped node ID. + */ + public UUID nodeId() { + return nodeId; + } + + /** + * @param nodeId Node ID. + */ + public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } + + /** + * @return Subject ID. + */ + public UUID subjectId() { + return subjId; + } + + /** + * @return Task name hash. + */ + public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Future version. + */ + public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @return Flag indicating whether this is fast-map udpate. + */ + public boolean fastMap() { + return fastMap; + } + + /** + * @return Update version for fast-map request. + */ + public GridCacheVersion updateVersion() { + return updateVer; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Topology locked flag. + */ + public boolean topologyLocked() { + return topLocked; + } + + /** + * @return {@code True} if request sent from client node. + */ + public boolean clientRequest() { + return clientReq; + } + + /** + * @return Cache write synchronization mode. + */ + public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } + + /** + * @return Expiry policy. + */ + public ExpiryPolicy expiry() { + return expiryPlc; + } + + /** + * @return Return value flag. + */ + public boolean returnValue() { + return retval; + } + + /** + * @return Filter. + */ + @Nullable public CacheEntryPredicate[] filter() { + return filter; + } + + /** + * @return Skip write-through to a persistent storage. + */ + public boolean skipStore() { + return skipStore; + } + + /** + * @return Keep binary flag. + */ + public boolean keepBinary() { + return keepBinary; + } + + /** + * @param key Key to add. + * @param val Optional update value. + * @param conflictTtl Conflict TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param primary If given key is primary on this mapping. + */ + public void addUpdateEntry(KeyCacheObject key, + @Nullable Object val, + long conflictTtl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, + boolean primary) { + EntryProcessor entryProcessor = null; + + if (op == TRANSFORM) { + assert val instanceof EntryProcessor : val; + + entryProcessor = (EntryProcessor) val; + } + + assert val != null || op == DELETE; + + keys.add(key); + + if (entryProcessor != null) { + if (entryProcessors == null) + entryProcessors = new ArrayList<>(initSize); + + entryProcessors.add(entryProcessor); + } + else if (val != null) { + assert val instanceof CacheObject : val; + + if (vals == null) + vals = new ArrayList<>(initSize); + + vals.add((CacheObject)val); + } + + hasPrimary |= primary; + + // In case there is no conflict, do not create the list. + if (conflictVer != null) { + if (conflictVers == null) { + conflictVers = new ArrayList<>(initSize); + + for (int i = 0; i < keys.size() - 1; i++) + conflictVers.add(null); + } + + conflictVers.add(conflictVer); + } + else if (conflictVers != null) + conflictVers.add(null); + + if (conflictTtl >= 0) { + if (conflictTtls == null) { + conflictTtls = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictTtls.add(CU.TTL_NOT_CHANGED); + } + + conflictTtls.add(conflictTtl); + } + + if (conflictExpireTime >= 0) { + if (conflictExpireTimes == null) { + conflictExpireTimes = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + + conflictExpireTimes.add(conflictExpireTime); + } + } + + /** + * @return Keys for this update request. + */ + public List keys() { + return keys; + } + + /** + * @return Values for this update request. + */ + public List values() { + return op == TRANSFORM ? entryProcessors : vals; + } + + /** + * @return Update operation. + */ + public GridCacheOperation operation() { + return op; + } + + /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** + * @param idx Key index. + * @return Value. + */ + @SuppressWarnings("unchecked") + public CacheObject value(int idx) { + assert op == UPDATE : op; + + return vals.get(idx); + } + + /** + * @param idx Key index. + * @return Entry processor. + */ + @SuppressWarnings("unchecked") + public EntryProcessor entryProcessor(int idx) { + assert op == TRANSFORM : op; + + return entryProcessors.get(idx); + } + + /** + * @param idx Index to get. + * @return Write value - either value, or transform closure. + */ + public CacheObject writeValue(int idx) { + if (vals != null) + return vals.get(idx); + + return null; + } + + /** + * @return Conflict versions. + */ + @Nullable public List conflictVersions() { + return conflictVers; + } + + /** + * @param idx Index. + * @return Conflict version. + */ + @Nullable public GridCacheVersion conflictVersion(int idx) { + if (conflictVers != null) { + assert idx >= 0 && idx < conflictVers.size(); + + return conflictVers.get(idx); + } + + return null; + } + + /** + * @param idx Index. + * @return Conflict TTL. + */ + public long conflictTtl(int idx) { + if (conflictTtls != null) { + assert idx >= 0 && idx < conflictTtls.size(); + + return conflictTtls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** + * @param idx Index. + * @return Conflict expire time. + */ + public long conflictExpireTime(int idx) { + if (conflictExpireTimes != null) { + assert idx >= 0 && idx < conflictExpireTimes.size(); + + return conflictExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** + * @return Flag indicating whether this request contains primary keys. + */ + public boolean hasPrimary() { + return hasPrimary; + } + + /** + * @param res Response. + * @return {@code True} if current response was {@code null}. + */ + public boolean onResponse(GridNearAtomicUpdateResponse res) { + if (this.res == null) { + this.res = res; + + return true; + } + + return false; + } + + /** + * @return Response. + */ + @Nullable public GridNearAtomicUpdateResponse response() { + return res; + } + + /** {@inheritDoc} + * @param ctx*/ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(keys, cctx); + + if (filter != null) { + boolean hasFilter = false; + + for (CacheEntryPredicate p : filter) { + if (p != null) { + hasFilter = true; + + p.prepareMarshal(cctx); + } + } + + if (!hasFilter) + filter = null; + } + + if (expiryPlc != null && expiryPlcBytes == null) + expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); + + if (op == TRANSFORM) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (entryProcessorsBytes == null) + entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + } + else + prepareMarshalCacheObjects(vals, cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(keys, cctx, ldr); + + if (op == TRANSFORM) { + if (entryProcessors == null) + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + } + else + finishUnmarshalCacheObjects(vals, cctx, ldr); + + if (filter != null) { + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + + if (expiryPlcBytes != null && expiryPlc == null) + expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeBoolean("clientReq", clientReq)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("conflictTtls", conflictTtls)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("fastMap", fastMap)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBoolean("hasPrimary", hasPrimary)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeBoolean("retval", retval)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeBoolean("skipStore", skipStore)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeBoolean("topLocked", topLocked)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("updateVer", updateVer)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + 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: + clientReq = reader.readBoolean("clientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + conflictTtls = reader.readMessage("conflictTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + fastMap = reader.readBoolean("fastMap"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + hasPrimary = reader.readBoolean("hasPrimary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + keys = reader.readCollection("keys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + byte opOrd; + + opOrd = reader.readByte("op"); + + if (!reader.isLastRead()) + return false; + + op = GridCacheOperation.fromOrdinal(opOrd); + + reader.incrementState(); + + case 17: + retval = reader.readBoolean("retval"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + skipStore = reader.readBoolean("skipStore"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 19: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + byte syncModeOrd; + + syncModeOrd = reader.readByte("syncMode"); + + if (!reader.isLastRead()) + return false; + + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + + reader.incrementState(); + + case 21: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + topLocked = reader.readBoolean("topLocked"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + updateVer = reader.readMessage("updateVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearAtomicSingleUpdateRequest.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return -23; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 26; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicSingleUpdateRequest.class, this, "filter", Arrays.toString(filter), + "parent", super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 519df178c8410..8b1673f37ac0a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -17,16 +17,7 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; -import javax.cache.expiry.ExpiryPolicy; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteLogger; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -35,16 +26,12 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException; -import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; -import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.GridCacheTryPutFailedException; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.future.GridFinishedFuture; @@ -57,35 +44,26 @@ import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; +import javax.cache.expiry.ExpiryPolicy; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; + import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC; import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; /** * DHT atomic cache near update future. */ -public class GridNearAtomicUpdateFuture extends GridFutureAdapter - implements GridCacheAtomicFuture{ - /** Logger reference. */ - private static final AtomicReference logRef = new AtomicReference<>(); - - /** Logger. */ - protected static IgniteLogger log; - - /** Cache context. */ - private final GridCacheContext cctx; - - /** Cache. */ - private GridDhtAtomicCache cache; - - /** Update operation. */ - private final GridCacheOperation op; - +public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFuture + { /** Keys */ private Collection keys; @@ -93,9 +71,6 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection vals; - /** Optional arguments for entry processor. */ - private Object[] invokeArgs; - /** Conflict put values. */ @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection conflictPutVals; @@ -104,48 +79,6 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection conflictRmvVals; - /** Return value require flag. */ - private final boolean retval; - - /** Expiry policy. */ - private final ExpiryPolicy expiryPlc; - - /** Optional filter. */ - private final CacheEntryPredicate[] filter; - - /** Write synchronization mode. */ - private final CacheWriteSynchronizationMode syncMode; - - /** Raw return value flag. */ - private final boolean rawRetval; - - /** Fast map flag. */ - private final boolean fastMap; - - /** Near cache flag. */ - private final boolean nearEnabled; - - /** Subject ID. */ - private final UUID subjId; - - /** Task name hash. */ - private final int taskNameHash; - - /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ - private boolean topLocked; - - /** Skip store flag. */ - private final boolean skipStore; - - /** */ - private final boolean keepBinary; - - /** Wait for topology future flag. */ - private final boolean waitTopFut; - - /** Remap count. */ - private int remapCnt; - /** State. */ private final UpdateState state; @@ -191,66 +124,27 @@ public GridNearAtomicUpdateFuture( int remapCnt, boolean waitTopFut ) { - this.rawRetval = rawRetval; + super(cctx, cache, syncMode, op, invokeArgs, retval, rawRetval, expiryPlc, filter, subjId, taskNameHash, + skipStore, keepBinary, remapCnt, waitTopFut); assert vals == null || vals.size() == keys.size(); assert conflictPutVals == null || conflictPutVals.size() == keys.size(); assert conflictRmvVals == null || conflictRmvVals.size() == keys.size(); assert subjId != null; - this.cctx = cctx; - this.cache = cache; - this.syncMode = syncMode; - this.op = op; this.keys = keys; this.vals = vals; - this.invokeArgs = invokeArgs; this.conflictPutVals = conflictPutVals; this.conflictRmvVals = conflictRmvVals; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.waitTopFut = waitTopFut; - - if (log == null) - log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); - - fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && - cctx.config().getAtomicWriteOrderMode() == CLOCK && - !(cctx.writeThrough() && cctx.config().getInterceptor() != null); - - nearEnabled = CU.isNearEnabled(cctx); - - if (!waitTopFut) - remapCnt = 1; - - this.remapCnt = remapCnt; state = new UpdateState(); } - /** {@inheritDoc} */ - @Override public IgniteUuid futureId() { - throw new UnsupportedOperationException(); - } - /** {@inheritDoc} */ @Override public GridCacheVersion version() { return state.futureVersion(); } - /** - * @return {@code True} if this future should block partition map exchange. - */ - private boolean waitForPartitionExchange() { - // Wait fast-map near atomic update futures in CLOCK mode. - return fastMap; - } - /** {@inheritDoc} */ @Override public Collection keys() { return keys; @@ -263,16 +157,6 @@ private boolean waitForPartitionExchange() { return false; } - /** {@inheritDoc} */ - @Override public boolean trackable() { - return true; - } - - /** {@inheritDoc} */ - @Override public void markNotTrackable() { - // No-op. - } - /** * Performs future mapping. */ @@ -344,23 +228,6 @@ public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { state.onResult(nodeId, res, false); } - /** - * Updates near cache. - * - * @param req Update request. - * @param res Update response. - */ - private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { - assert nearEnabled; - - if (res.remapKeys() != null || !req.hasPrimary()) - return; - - GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); - - near.processNearAtomicUpdateResponse(req, res); - } - /** * Maps future on ready topology. */ @@ -417,35 +284,6 @@ private void mapOnTopology() { state.map(topVer, null); } - /** - * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. - */ - private boolean storeFuture() { - return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; - } - - /** - * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near - * node and send updates in parallel to all participating nodes. - * - * @param key Key to map. - * @param topVer Topology version to map. - * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. - * @return Collection of nodes to which key is mapped. - */ - private Collection mapKey( - KeyCacheObject key, - AffinityTopologyVersion topVer, - boolean fastMap - ) { - GridCacheAffinityManager affMgr = cctx.affinity(); - - // If we can send updates in parallel - do it. - return fastMap ? - cctx.topology().nodes(affMgr.partition(key), topVer) : - Collections.singletonList(affMgr.primary(key, topVer)); - } - /** * Maps future to single node. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 1a7fa88191730..340dbf69f11b8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -57,7 +57,8 @@ /** * Lite DHT cache update request sent from near node to primary node. */ -public class GridNearAtomicUpdateRequest extends GridCacheMessage implements GridCacheDeployable { +public class GridNearAtomicUpdateRequest extends GridCacheMessage + implements GridNearAtomicUpdateRequestInterface, GridCacheDeployable { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java new file mode 100644 index 0000000000000..9f1775643d85d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.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.dht.atomic; + +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheOperation; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.jetbrains.annotations.Nullable; + +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.processor.EntryProcessor; +import java.util.List; +import java.util.UUID; + +/** + * Base interface for near atomic update interfaces. + */ +public interface GridNearAtomicUpdateRequestInterface { + public List keys(); + + public AffinityTopologyVersion topologyVersion(); + + public GridCacheVersion futureVersion(); + + public boolean returnValue(); + + public int taskNameHash(); + + /** + * @return Flag indicating whether this is fast-map udpate. + */ + public boolean fastMap(); + + /** + * @return Update version for fast-map request. + */ + public GridCacheVersion updateVersion(); + + public boolean clientRequest(); + + public boolean topologyLocked(); + + public ExpiryPolicy expiry(); + + public boolean skipStore(); + + public GridCacheOperation operation(); + + public CacheWriteSynchronizationMode writeSynchronizationMode(); + + public UUID subjectId(); + + @Nullable public Object[] invokeArguments(); + + public boolean keepBinary(); + + @Nullable public CacheEntryPredicate[] filter(); + + public UUID nodeId(); + + public void nodeId(UUID nodeId); + + public boolean hasPrimary(); + + @Nullable public List conflictVersions(); + + @Nullable public GridCacheVersion conflictVersion(int idx); + + public long conflictTtl(int idx); + + public long conflictExpireTime(int idx); + + public List values(); + + public CacheObject value(int idx); + + public long messageId(); + + public EntryProcessor entryProcessor(int idx); + + public CacheObject writeValue(int idx); +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 63c073d56be1b..2a91968981c44 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -45,7 +45,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestInterface; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx; @@ -127,7 +127,7 @@ public void dht(GridDhtAtomicCache dht) { * @param res Update response. */ public void processNearAtomicUpdateResponse( - GridNearAtomicUpdateRequest req, + GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res ) { if (F.size(res.failedKeys()) == req.keys().size()) From 29c2aee6b6ffac4f27da3732575f7d82b0e8bedd Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 11:09:13 +0300 Subject: [PATCH 03/34] IGNITE-2532: WIP. Only refactorings for now. --- .../cache/GridCacheAtomicFuture.java | 6 - .../dht/atomic/GridDhtAtomicUpdateFuture.java | 5 - .../GridNearAtomicSingleUpdateFuture.java | 1264 ----------------- .../atomic/GridNearAtomicUpdateFuture.java | 1179 ++++++++------- 4 files changed, 572 insertions(+), 1882 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java index 359909ed0d400..be24191d4cdd5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.cache; -import java.util.Collection; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -38,9 +37,4 @@ public interface GridCacheAtomicFuture extends GridCacheFuture { * @return Future or {@code null} if no need to wait. */ public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer); - - /** - * @return Future keys. - */ - public Collection keys(); } \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 6891d3b5c9659..9fe60c9bfa23b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -201,11 +201,6 @@ private boolean registerResponse(UUID nodeId) { return null; } - /** {@inheritDoc} */ - @Override public Collection keys() { - return keys; - } - /** * @param entry Entry to map. * @param val Value to write. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java deleted file mode 100644 index d633e479bc0ef..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java +++ /dev/null @@ -1,1264 +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.atomic; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteLogger; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.cluster.ClusterNode; -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.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException; -import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; -import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; -import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.GridCacheReturn; -import org.apache.ignite.internal.processors.cache.GridCacheTryPutFailedException; -import org.apache.ignite.internal.processors.cache.KeyCacheObject; -import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; -import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; -import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.future.GridFinishedFuture; -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.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.IgniteUuid; -import org.jetbrains.annotations.Nullable; - -import javax.cache.expiry.ExpiryPolicy; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - -import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; - -/** - * DHT atomic cache single near update future. - */ -public class GridNearAtomicSingleUpdateFuture extends GridFutureAdapter - implements GridCacheAtomicFuture{ - /** Logger reference. */ - private static final AtomicReference logRef = new AtomicReference<>(); - - /** Logger. */ - protected static IgniteLogger log; - - /** Cache context. */ - private final GridCacheContext cctx; - - /** Cache. */ - private GridDhtAtomicCache cache; - - /** Update operation. */ - private final GridCacheOperation op; - - /** Keys */ - private Collection keys; - - /** Values. */ - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) - private Collection vals; - - /** Optional arguments for entry processor. */ - private Object[] invokeArgs; - - /** Conflict put values. */ - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) - private Collection conflictPutVals; - - /** Conflict remove values. */ - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) - private Collection conflictRmvVals; - - /** Return value require flag. */ - private final boolean retval; - - /** Expiry policy. */ - private final ExpiryPolicy expiryPlc; - - /** Optional filter. */ - private final CacheEntryPredicate[] filter; - - /** Write synchronization mode. */ - private final CacheWriteSynchronizationMode syncMode; - - /** Raw return value flag. */ - private final boolean rawRetval; - - /** Fast map flag. */ - private final boolean fastMap; - - /** Near cache flag. */ - private final boolean nearEnabled; - - /** Subject ID. */ - private final UUID subjId; - - /** Task name hash. */ - private final int taskNameHash; - - /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ - private boolean topLocked; - - /** Skip store flag. */ - private final boolean skipStore; - - /** */ - private final boolean keepBinary; - - /** Wait for topology future flag. */ - private final boolean waitTopFut; - - /** Remap count. */ - private int remapCnt; - - /** State. */ - private final UpdateState state; - - /** - * @param cctx Cache context. - * @param cache Cache instance. - * @param syncMode Write synchronization mode. - * @param op Update operation. - * @param keys Keys to update. - * @param vals Values or transform closure. - * @param invokeArgs Optional arguments for entry processor. - * @param conflictPutVals Conflict put values (optional). - * @param conflictRmvVals Conflict remove values (optional). - * @param retval Return value require flag. - * @param rawRetval {@code True} if should return {@code GridCacheReturn} as future result. - * @param expiryPlc Expiry policy explicitly specified for cache operation. - * @param filter Entry filter. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param skipStore Skip store flag. - * @param keepBinary Keep binary flag. - * @param remapCnt Maximum number of retries. - * @param waitTopFut If {@code false} does not wait for affinity change future. - */ - public GridNearAtomicSingleUpdateFuture( - GridCacheContext cctx, - GridDhtAtomicCache cache, - CacheWriteSynchronizationMode syncMode, - GridCacheOperation op, - Collection keys, - @Nullable Collection vals, - @Nullable Object[] invokeArgs, - @Nullable Collection conflictPutVals, - @Nullable Collection conflictRmvVals, - final boolean retval, - final boolean rawRetval, - @Nullable ExpiryPolicy expiryPlc, - final CacheEntryPredicate[] filter, - UUID subjId, - int taskNameHash, - boolean skipStore, - boolean keepBinary, - int remapCnt, - boolean waitTopFut - ) { - this.rawRetval = rawRetval; - - assert vals == null || vals.size() == keys.size(); - assert conflictPutVals == null || conflictPutVals.size() == keys.size(); - assert conflictRmvVals == null || conflictRmvVals.size() == keys.size(); - assert subjId != null; - - this.cctx = cctx; - this.cache = cache; - this.syncMode = syncMode; - this.op = op; - this.keys = keys; - this.vals = vals; - this.invokeArgs = invokeArgs; - this.conflictPutVals = conflictPutVals; - this.conflictRmvVals = conflictRmvVals; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.waitTopFut = waitTopFut; - - if (log == null) - log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); - - fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && - cctx.config().getAtomicWriteOrderMode() == CLOCK && - !(cctx.writeThrough() && cctx.config().getInterceptor() != null); - - nearEnabled = CU.isNearEnabled(cctx); - - if (!waitTopFut) - remapCnt = 1; - - this.remapCnt = remapCnt; - - state = new UpdateState(); - } - - /** {@inheritDoc} */ - @Override public IgniteUuid futureId() { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion version() { - return state.futureVersion(); - } - - /** - * @return {@code True} if this future should block partition map exchange. - */ - private boolean waitForPartitionExchange() { - // Wait fast-map near atomic update futures in CLOCK mode. - return fastMap; - } - - /** {@inheritDoc} */ - @Override public Collection keys() { - return keys; - } - - /** {@inheritDoc} */ - @Override public boolean onNodeLeft(UUID nodeId) { - state.onNodeLeft(nodeId); - - return false; - } - - /** {@inheritDoc} */ - @Override public boolean trackable() { - return true; - } - - /** {@inheritDoc} */ - @Override public void markNotTrackable() { - // No-op. - } - - /** - * Performs future mapping. - */ - public void map() { - AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); - - if (topVer == null) - mapOnTopology(); - else { - topLocked = true; - - // Cannot remap. - remapCnt = 1; - - state.map(topVer, null); - } - } - - /** {@inheritDoc} */ - @Override public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer) { - if (waitForPartitionExchange()) { - GridFutureAdapter fut = state.completeFuture(topVer); - - if (fut != null && isDone()) { - fut.onDone(); - - return null; - } - - return fut; - } - - return null; - } - - /** {@inheritDoc} */ - @SuppressWarnings("ConstantConditions") - @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) { - assert res == null || res instanceof GridCacheReturn; - - GridCacheReturn ret = (GridCacheReturn)res; - - Object retval = - res == null ? null : rawRetval ? ret : (this.retval || op == TRANSFORM) ? - cctx.unwrapBinaryIfNeeded(ret.value(), keepBinary) : ret.success(); - - if (op == TRANSFORM && retval == null) - retval = Collections.emptyMap(); - - if (super.onDone(retval, err)) { - GridCacheVersion futVer = state.onFutureDone(); - - if (futVer != null) - cctx.mvcc().removeAtomicFuture(futVer); - - return true; - } - - return false; - } - - /** - * Response callback. - * - * @param nodeId Node ID. - * @param res Update response. - */ - public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { - state.onResult(nodeId, res, false); - } - - /** - * Updates near cache. - * - * @param req Update request. - * @param res Update response. - */ - private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { - assert nearEnabled; - - if (res.remapKeys() != null || !req.hasPrimary()) - return; - - GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); - - near.processNearAtomicUpdateResponse(req, res); - } - - /** - * Maps future on ready topology. - */ - private void mapOnTopology() { - cache.topology().readLock(); - - AffinityTopologyVersion topVer = null; - - try { - if (cache.topology().stopping()) { - onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " + - cache.name())); - - return; - } - - GridDhtTopologyFuture fut = cache.topology().topologyVersionFuture(); - - if (fut.isDone()) { - Throwable err = fut.validateCache(cctx); - - if (err != null) { - onDone(err); - - return; - } - - topVer = fut.topologyVersion(); - } - else { - if (waitTopFut) { - assert !topLocked : this; - - fut.listen(new CI1>() { - @Override public void apply(IgniteInternalFuture t) { - cctx.kernalContext().closure().runLocalSafe(new Runnable() { - @Override public void run() { - mapOnTopology(); - } - }); - } - }); - } - else - onDone(new GridCacheTryPutFailedException()); - - return; - } - } - finally { - cache.topology().readUnlock(); - } - - state.map(topVer, null); - } - - /** - * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. - */ - private boolean storeFuture() { - return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; - } - - /** - * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near - * node and send updates in parallel to all participating nodes. - * - * @param key Key to map. - * @param topVer Topology version to map. - * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. - * @return Collection of nodes to which key is mapped. - */ - private Collection mapKey( - KeyCacheObject key, - AffinityTopologyVersion topVer, - boolean fastMap - ) { - GridCacheAffinityManager affMgr = cctx.affinity(); - - // If we can send updates in parallel - do it. - return fastMap ? - cctx.topology().nodes(affMgr.partition(key), topVer) : - Collections.singletonList(affMgr.primary(key, topVer)); - } - - /** - * Maps future to single node. - * - * @param nodeId Node ID. - * @param req Request. - */ - private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { - if (cctx.localNodeId().equals(nodeId)) { - cache.updateAllAsyncInternal(nodeId, req, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { - onResult(res.nodeId(), res); - } - }); - } - else { - try { - if (log.isDebugEnabled()) - log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - - cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); - - if (syncMode == FULL_ASYNC) - onDone(new GridCacheReturn(cctx, true, true, null, true)); - } - catch (IgniteCheckedException e) { - state.onSendError(req, e); - } - } - } - - /** - * Sends messages to remote nodes and updates local cache. - * - * @param mappings Mappings to send. - */ - private void doUpdate(Map mappings) { - UUID locNodeId = cctx.localNodeId(); - - GridNearAtomicUpdateRequest locUpdate = null; - - // Send messages to remote nodes first, then run local update. - for (GridNearAtomicUpdateRequest req : mappings.values()) { - if (locNodeId.equals(req.nodeId())) { - assert locUpdate == null : "Cannot have more than one local mapping [locUpdate=" + locUpdate + - ", req=" + req + ']'; - - locUpdate = req; - } - else { - try { - if (log.isDebugEnabled()) - log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - - cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); - } - catch (IgniteCheckedException e) { - state.onSendError(req, e); - } - } - } - - if (locUpdate != null) { - cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { - onResult(res.nodeId(), res); - } - }); - } - - if (syncMode == FULL_ASYNC) - onDone(new GridCacheReturn(cctx, true, true, null, true)); - } - - /** - * - */ - private class UpdateState { - /** Current topology version. */ - private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; - - /** */ - private GridCacheVersion updVer; - - /** Topology version when got mapping error. */ - private AffinityTopologyVersion mapErrTopVer; - - /** Mappings if operations is mapped to more than one node. */ - @GridToStringInclude - private Map mappings; - - /** */ - private int resCnt; - - /** Error. */ - private CachePartialUpdateCheckedException err; - - /** Future ID. */ - private GridCacheVersion futVer; - - /** Completion future for a particular topology version. */ - private GridFutureAdapter topCompleteFut; - - /** Keys to remap. */ - private Collection remapKeys; - - /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequest singleReq; - - /** Operation result. */ - private GridCacheReturn opRes; - - /** - * @return Future version. - */ - @Nullable synchronized GridCacheVersion futureVersion() { - return futVer; - } - - /** - * @param nodeId Left node ID. - */ - void onNodeLeft(UUID nodeId) { - GridNearAtomicUpdateResponse res = null; - - synchronized (this) { - GridNearAtomicUpdateRequest req; - - if (singleReq != null) - req = singleReq.nodeId().equals(nodeId) ? singleReq : null; - else - req = mappings != null ? mappings.get(nodeId) : null; - - if (req != null && req.response() == null) { - res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); - - ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + - "before response is received: " + nodeId); - - e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); - - res.addFailedKeys(req.keys(), e); - } - } - - if (res != null) - onResult(nodeId, res, true); - } - - /** - * @param nodeId Node ID. - * @param res Response. - * @param nodeErr {@code True} if response was created on node failure. - */ - @SuppressWarnings("unchecked") - void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequest req; - - AffinityTopologyVersion remapTopVer = null; - - GridCacheReturn opRes0 = null; - CachePartialUpdateCheckedException err0 = null; - - boolean rcvAll; - - GridFutureAdapter fut0 = null; - - synchronized (this) { - if (!res.futureVersion().equals(futVer)) - return; - - if (singleReq != null) { - if (!singleReq.nodeId().equals(nodeId)) - return; - - req = singleReq; - - singleReq = null; - - rcvAll = true; - } - else { - req = mappings != null ? mappings.get(nodeId) : null; - - if (req != null && req.onResponse(res)) { - resCnt++; - - rcvAll = mappings.size() == resCnt; - } - else - return; - } - - assert req != null && req.topologyVersion().equals(topVer) : req; - - if (res.remapKeys() != null) { - assert !fastMap || cctx.kernalContext().clientNode(); - - if (remapKeys == null) - remapKeys = U.newHashSet(res.remapKeys().size()); - - remapKeys.addAll(res.remapKeys()); - - if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) - mapErrTopVer = req.topologyVersion(); - } - else if (res.error() != null) { - if (res.failedKeys() != null) - addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); - } - else { - if (!req.fastMap() || req.hasPrimary()) { - GridCacheReturn ret = res.returnValue(); - - if (op == TRANSFORM) { - if (ret != null) - addInvokeResults(ret); - } - else - opRes = ret; - } - } - - if (rcvAll) { - if (remapKeys != null) { - assert mapErrTopVer != null; - - remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); - } - else { - if (err != null && - X.hasCause(err, CachePartialUpdateCheckedException.class) && - X.hasCause(err, ClusterTopologyCheckedException.class) && - storeFuture() && - --remapCnt > 0) { - ClusterTopologyCheckedException topErr = - X.cause(err, ClusterTopologyCheckedException.class); - - if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { - CachePartialUpdateCheckedException cause = - X.cause(err, CachePartialUpdateCheckedException.class); - - assert cause != null && cause.topologyVersion() != null : err; - - remapTopVer = - new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); - - err = null; - - Collection failedKeys = cause.failedKeys(); - - remapKeys = new ArrayList<>(failedKeys.size()); - - for (Object key : failedKeys) - remapKeys.add(cctx.toCacheKeyObject(key)); - - updVer = null; - } - } - } - - if (remapTopVer == null) { - err0 = err; - opRes0 = opRes; - } - else { - fut0 = topCompleteFut; - - topCompleteFut = null; - - cctx.mvcc().removeAtomicFuture(futVer); - - futVer = null; - topVer = AffinityTopologyVersion.ZERO; - } - } - } - - if (res.error() != null && res.failedKeys() == null) { - onDone(res.error()); - - return; - } - - if (rcvAll && nearEnabled) { - if (mappings != null) { - for (GridNearAtomicUpdateRequest req0 : mappings.values()) { - GridNearAtomicUpdateResponse res0 = req0.response(); - - assert res0 != null : req0; - - updateNear(req0, res0); - } - } - else if (!nodeErr) - updateNear(req, res); - } - - if (remapTopVer != null) { - if (fut0 != null) - fut0.onDone(); - - if (!waitTopFut) { - onDone(new GridCacheTryPutFailedException()); - - return; - } - - if (topLocked) { - assert !F.isEmpty(remapKeys) : remapKeys; - - CachePartialUpdateCheckedException e = - new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - - ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( - "Failed to update keys, topology changed while execute atomic update inside transaction."); - - cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); - - e.add(remapKeys, cause); - - onDone(e); - - return; - } - - IgniteInternalFuture fut = - cctx.shared().exchange().affinityReadyFuture(remapTopVer); - - if (fut == null) - fut = new GridFinishedFuture<>(remapTopVer); - - fut.listen(new CI1>() { - @Override public void apply(final IgniteInternalFuture fut) { - cctx.kernalContext().closure().runLocalSafe(new Runnable() { - @Override public void run() { - try { - AffinityTopologyVersion topVer = fut.get(); - - map(topVer, remapKeys); - } - catch (IgniteCheckedException e) { - onDone(e); - } - } - }); - } - }); - - return; - } - - if (rcvAll) - onDone(opRes0, err0); - } - - /** - * @param req Request. - * @param e Error. - */ - void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { - synchronized (this) { - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); - - res.addFailedKeys(req.keys(), e); - - onResult(req.nodeId(), res, true); - } - } - - /** - * @param topVer Topology version. - * @param remapKeys Keys to remap. - */ - void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { - Collection topNodes = CU.affinityNodes(cctx, topVer); - - if (F.isEmpty(topNodes)) { - onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid).")); - - return; - } - - Exception err = null; - GridNearAtomicUpdateRequest singleReq0 = null; - Map mappings0 = null; - - int size = keys.size(); - - GridCacheVersion futVer = cctx.versions().next(topVer); - - GridCacheVersion updVer; - - // Assign version on near node in CLOCK ordering mode even if fastMap is false. - if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { - updVer = this.updVer; - - if (updVer == null) { - updVer = cctx.versions().next(topVer); - - if (log.isDebugEnabled()) - log.debug("Assigned fast-map version for update on near node: " + updVer); - } - } - else - updVer = null; - - try { - if (size == 1 && !fastMap) { - assert remapKeys == null || remapKeys.size() == 1; - - singleReq0 = mapSingleUpdate(topVer, futVer, updVer); - } - else { - Map pendingMappings = mapUpdate(topNodes, - topVer, - futVer, - updVer, - remapKeys); - - if (pendingMappings.size() == 1) - singleReq0 = F.firstValue(pendingMappings); - else { - if (syncMode == PRIMARY_SYNC) { - mappings0 = U.newHashMap(pendingMappings.size()); - - for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { - if (req.hasPrimary()) - mappings0.put(req.nodeId(), req); - } - } - else - mappings0 = pendingMappings; - - assert !mappings0.isEmpty() || size == 0 : GridNearAtomicSingleUpdateFuture.this; - } - } - - synchronized (this) { - assert this.futVer == null : this; - assert this.topVer == AffinityTopologyVersion.ZERO : this; - - this.topVer = topVer; - this.updVer = updVer; - this.futVer = futVer; - - resCnt = 0; - - singleReq = singleReq0; - mappings = mappings0; - - this.remapKeys = null; - } - } - catch (Exception e) { - err = e; - } - - if (err != null) { - onDone(err); - - return; - } - - if (storeFuture()) { - if (!cctx.mvcc().addAtomicFuture(futVer, GridNearAtomicSingleUpdateFuture.this)) { - assert isDone() : GridNearAtomicSingleUpdateFuture.this; - - return; - } - } - - // Optimize mapping for single key. - if (singleReq0 != null) - mapSingle(singleReq0.nodeId(), singleReq0); - else { - assert mappings0 != null; - - if (size == 0) - onDone(new GridCacheReturn(cctx, true, true, null, true)); - else - doUpdate(mappings0); - } - } - - /** - * @param topVer Topology version. - * @return Future. - */ - @Nullable synchronized GridFutureAdapter completeFuture(AffinityTopologyVersion topVer) { - if (this.topVer == AffinityTopologyVersion.ZERO) - return null; - - if (this.topVer.compareTo(topVer) < 0) { - if (topCompleteFut == null) - topCompleteFut = new GridFutureAdapter<>(); - - return topCompleteFut; - } - - return null; - } - - /** - * @return Future version. - */ - GridCacheVersion onFutureDone() { - GridCacheVersion ver0; - - GridFutureAdapter fut0; - - synchronized (this) { - fut0 = topCompleteFut; - - topCompleteFut = null; - - ver0 = futVer; - - futVer = null; - } - - if (fut0 != null) - fut0.onDone(); - - return ver0; - } - - /** - * @param topNodes Cache nodes. - * @param topVer Topology version. - * @param futVer Future version. - * @param updVer Update version. - * @param remapKeys Keys to remap. - * @return Mapping. - * @throws Exception If failed. - */ - private Map mapUpdate(Collection topNodes, - AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer, - @Nullable Collection remapKeys) throws Exception { - Iterator it = null; - - if (vals != null) - it = vals.iterator(); - - Iterator conflictPutValsIt = null; - - if (conflictPutVals != null) - conflictPutValsIt = conflictPutVals.iterator(); - - Iterator conflictRmvValsIt = null; - - if (conflictRmvVals != null) - conflictRmvValsIt = conflictRmvVals.iterator(); - - Map pendingMappings = U.newHashMap(topNodes.size()); - - // Create mappings first, then send messages. - for (Object key : keys) { - if (key == null) - throw new NullPointerException("Null key."); - - Object val; - GridCacheVersion conflictVer; - long conflictTtl; - long conflictExpireTime; - - if (vals != null) { - val = it.next(); - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - - if (val == null) - throw new NullPointerException("Null value."); - } - else if (conflictPutVals != null) { - GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); - - val = conflictPutVal.valueEx(); - conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); - conflictExpireTime = conflictPutVal.expireTime(); - } - else if (conflictRmvVals != null) { - val = null; - conflictVer = conflictRmvValsIt.next(); - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else { - val = null; - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - - if (val == null && op != GridCacheOperation.DELETE) - continue; - - KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); - - if (remapKeys != null && !remapKeys.contains(cacheKey)) - continue; - - if (op != TRANSFORM) - val = cctx.toCacheObject(val); - - Collection affNodes = mapKey(cacheKey, topVer, fastMap); - - if (affNodes.isEmpty()) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); - - int i = 0; - - for (ClusterNode affNode : affNodes) { - if (affNode == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); - - UUID nodeId = affNode.id(); - - GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); - - if (mapped == null) { - mapped = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - keys.size()); - - pendingMappings.put(nodeId, mapped); - } - - mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); - - i++; - } - } - - return pendingMappings; - } - - /** - * @param topVer Topology version. - * @param futVer Future version. - * @param updVer Update version. - * @return Request. - * @throws Exception If failed. - */ - private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer) throws Exception { - Object key = F.first(keys); - - Object val; - GridCacheVersion conflictVer; - long conflictTtl; - long conflictExpireTime; - - if (vals != null) { - // Regular PUT. - val = F.first(vals); - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else if (conflictPutVals != null) { - // Conflict PUT. - GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); - - val = conflictPutVal.valueEx(); - conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); - conflictExpireTime = conflictPutVal.expireTime(); - } - else if (conflictRmvVals != null) { - // Conflict REMOVE. - val = null; - conflictVer = F.first(conflictRmvVals); - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else { - // Regular REMOVE. - val = null; - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - - // We still can get here if user pass map with single element. - if (key == null) - throw new NullPointerException("Null key."); - - if (val == null && op != GridCacheOperation.DELETE) - throw new NullPointerException("Null value."); - - KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); - - if (op != TRANSFORM) - val = cctx.toCacheObject(val); - - ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); - - if (primary == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid)."); - - GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - true); - - return req; - } - - /** - * @param ret Result from single node. - */ - @SuppressWarnings("unchecked") - private void addInvokeResults(GridCacheReturn ret) { - assert op == TRANSFORM : op; - assert ret.value() == null || ret.value() instanceof Map : ret.value(); - - if (ret.value() != null) { - if (opRes != null) - opRes.mergeEntryProcessResults(ret); - else - opRes = ret; - } - } - - /** - * @param failedKeys Failed keys. - * @param topVer Topology version for failed update. - * @param err Error cause. - */ - private void addFailedKeys(Collection failedKeys, - AffinityTopologyVersion topVer, - Throwable err) { - CachePartialUpdateCheckedException err0 = this.err; - - if (err0 == null) - err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - - Collection keys = new ArrayList<>(failedKeys.size()); - - for (KeyCacheObject key : failedKeys) - keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); - - err0.add(keys, err, topVer); - } - - /** {@inheritDoc} */ - @Override public synchronized String toString() { - return S.toString(UpdateState.class, this); - } - } - - /** {@inheritDoc} */ - public String toString() { - return S.toString(GridNearAtomicSingleUpdateFuture.class, this, super.toString()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 8b1673f37ac0a..2aa510dc37746 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -62,8 +62,8 @@ /** * DHT atomic cache near update future. */ -public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFuture - { +@SuppressWarnings("ThrowableResultOfMethodCallIgnored") +public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFuture { /** Keys */ private Collection keys; @@ -79,8 +79,39 @@ public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFutu @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection conflictRmvVals; - /** State. */ - private final UpdateState state; + /** Current topology version. */ + private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; + + /** */ + private GridCacheVersion updVer; + + /** Topology version when got mapping error. */ + private AffinityTopologyVersion mapErrTopVer; + + /** Mappings if operations is mapped to more than one node. */ + @GridToStringInclude + private Map mappings; + + /** */ + private int resCnt; + + /** Error. */ + private CachePartialUpdateCheckedException err; + + /** Future ID. */ + private GridCacheVersion futVer; + + /** Completion future for a particular topology version. */ + private GridFutureAdapter topCompleteFut; + + /** Keys to remap. */ + private Collection remapKeys; + + /** Not null is operation is mapped to single node. */ + private GridNearAtomicUpdateRequest singleReq; + + /** Operation result. */ + private GridCacheReturn opRes; /** * @param cctx Cache context. @@ -130,55 +161,22 @@ public GridNearAtomicUpdateFuture( assert vals == null || vals.size() == keys.size(); assert conflictPutVals == null || conflictPutVals.size() == keys.size(); assert conflictRmvVals == null || conflictRmvVals.size() == keys.size(); - assert subjId != null; this.keys = keys; this.vals = vals; this.conflictPutVals = conflictPutVals; this.conflictRmvVals = conflictRmvVals; - - state = new UpdateState(); - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion version() { - return state.futureVersion(); } /** {@inheritDoc} */ - @Override public Collection keys() { - return keys; - } - - /** {@inheritDoc} */ - @Override public boolean onNodeLeft(UUID nodeId) { - state.onNodeLeft(nodeId); - - return false; - } - - /** - * Performs future mapping. - */ - public void map() { - AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); - - if (topVer == null) - mapOnTopology(); - else { - topLocked = true; - - // Cannot remap. - remapCnt = 1; - - state.map(topVer, null); - } + @Override public synchronized GridCacheVersion version() { + return futVer; } /** {@inheritDoc} */ @Override public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer) { if (waitForPartitionExchange()) { - GridFutureAdapter fut = state.completeFuture(topVer); + GridFutureAdapter fut = completeFuture0(topVer); if (fut != null && isDone()) { fut.onDone(); @@ -192,6 +190,39 @@ public void map() { return null; } + /** {@inheritDoc} */ + @Override public boolean onNodeLeft(UUID nodeId) { + GridNearAtomicUpdateResponse res = null; + + synchronized (this) { + GridNearAtomicUpdateRequest req; + + if (singleReq != null) + req = singleReq.nodeId().equals(nodeId) ? singleReq : null; + else + req = mappings != null ? mappings.get(nodeId) : null; + + if (req != null && req.response() == null) { + res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); + + ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + + "before response is received: " + nodeId); + + e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); + + res.addFailedKeys(req.keys(), e); + } + } + + if (res != null) + onResult(nodeId, res, true); + + return false; + } + /** {@inheritDoc} */ @SuppressWarnings("ConstantConditions") @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) { @@ -207,7 +238,7 @@ public void map() { retval = Collections.emptyMap(); if (super.onDone(retval, err)) { - GridCacheVersion futVer = state.onFutureDone(); + GridCacheVersion futVer = onFutureDone(); if (futVer != null) cctx.mvcc().removeAtomicFuture(futVer); @@ -218,6 +249,24 @@ public void map() { return false; } + /** + * Performs future mapping. + */ + public void map() { + AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); + + if (topVer == null) + mapOnTopology(); + else { + topLocked = true; + + // Cannot remap. + remapCnt = 1; + + map(topVer, null); + } + } + /** * Response callback. * @@ -225,7 +274,7 @@ public void map() { * @param res Update response. */ public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { - state.onResult(nodeId, res, false); + onResult(nodeId, res, false); } /** @@ -281,7 +330,7 @@ private void mapOnTopology() { cache.topology().readUnlock(); } - state.map(topVer, null); + map(topVer, null); } /** @@ -310,7 +359,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { onDone(new GridCacheReturn(cctx, true, true, null, true)); } catch (IgniteCheckedException e) { - state.onSendError(req, e); + onSendError(req, e); } } } @@ -341,7 +390,7 @@ private void doUpdate(Map mappings) { cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); } catch (IgniteCheckedException e) { - state.onSendError(req, e); + onSendError(req, e); } } } @@ -360,610 +409,422 @@ private void doUpdate(Map mappings) { } /** - * + * @param nodeId Node ID. + * @param res Response. + * @param nodeErr {@code True} if response was created on node failure. */ - private class UpdateState { - /** Current topology version. */ - private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; - - /** */ - private GridCacheVersion updVer; - - /** Topology version when got mapping error. */ - private AffinityTopologyVersion mapErrTopVer; - - /** Mappings if operations is mapped to more than one node. */ - @GridToStringInclude - private Map mappings; - - /** */ - private int resCnt; - - /** Error. */ - private CachePartialUpdateCheckedException err; + @SuppressWarnings("unchecked") + void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { + GridNearAtomicUpdateRequest req; - /** Future ID. */ - private GridCacheVersion futVer; + AffinityTopologyVersion remapTopVer = null; - /** Completion future for a particular topology version. */ - private GridFutureAdapter topCompleteFut; + GridCacheReturn opRes0 = null; + CachePartialUpdateCheckedException err0 = null; - /** Keys to remap. */ - private Collection remapKeys; + boolean rcvAll; - /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequest singleReq; + GridFutureAdapter fut0 = null; - /** Operation result. */ - private GridCacheReturn opRes; - - /** - * @return Future version. - */ - @Nullable synchronized GridCacheVersion futureVersion() { - return futVer; - } - - /** - * @param nodeId Left node ID. - */ - void onNodeLeft(UUID nodeId) { - GridNearAtomicUpdateResponse res = null; - - synchronized (this) { - GridNearAtomicUpdateRequest req; - - if (singleReq != null) - req = singleReq.nodeId().equals(nodeId) ? singleReq : null; - else - req = mappings != null ? mappings.get(nodeId) : null; + synchronized (this) { + if (!res.futureVersion().equals(futVer)) + return; - if (req != null && req.response() == null) { - res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); + if (singleReq != null) { + if (!singleReq.nodeId().equals(nodeId)) + return; - ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + - "before response is received: " + nodeId); + req = singleReq; - e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); + singleReq = null; - res.addFailedKeys(req.keys(), e); - } + rcvAll = true; } + else { + req = mappings != null ? mappings.get(nodeId) : null; - if (res != null) - onResult(nodeId, res, true); - } - - /** - * @param nodeId Node ID. - * @param res Response. - * @param nodeErr {@code True} if response was created on node failure. - */ - @SuppressWarnings("unchecked") - void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequest req; - - AffinityTopologyVersion remapTopVer = null; - - GridCacheReturn opRes0 = null; - CachePartialUpdateCheckedException err0 = null; - - boolean rcvAll; - - GridFutureAdapter fut0 = null; + if (req != null && req.onResponse(res)) { + resCnt++; - synchronized (this) { - if (!res.futureVersion().equals(futVer)) + rcvAll = mappings.size() == resCnt; + } + else return; + } - if (singleReq != null) { - if (!singleReq.nodeId().equals(nodeId)) - return; + assert req != null && req.topologyVersion().equals(topVer) : req; - req = singleReq; + if (res.remapKeys() != null) { + assert !fastMap || cctx.kernalContext().clientNode(); - singleReq = null; + if (remapKeys == null) + remapKeys = U.newHashSet(res.remapKeys().size()); - rcvAll = true; - } - else { - req = mappings != null ? mappings.get(nodeId) : null; + remapKeys.addAll(res.remapKeys()); - if (req != null && req.onResponse(res)) { - resCnt++; + if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) + mapErrTopVer = req.topologyVersion(); + } + else if (res.error() != null) { + if (res.failedKeys() != null) + addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); + } + else { + if (!req.fastMap() || req.hasPrimary()) { + GridCacheReturn ret = res.returnValue(); - rcvAll = mappings.size() == resCnt; + if (op == TRANSFORM) { + if (ret != null) + addInvokeResults(ret); } else - return; + opRes = ret; } + } - assert req != null && req.topologyVersion().equals(topVer) : req; - - if (res.remapKeys() != null) { - assert !fastMap || cctx.kernalContext().clientNode(); - - if (remapKeys == null) - remapKeys = U.newHashSet(res.remapKeys().size()); - - remapKeys.addAll(res.remapKeys()); + if (rcvAll) { + if (remapKeys != null) { + assert mapErrTopVer != null; - if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) - mapErrTopVer = req.topologyVersion(); - } - else if (res.error() != null) { - if (res.failedKeys() != null) - addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); + remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); } else { - if (!req.fastMap() || req.hasPrimary()) { - GridCacheReturn ret = res.returnValue(); - - if (op == TRANSFORM) { - if (ret != null) - addInvokeResults(ret); - } - else - opRes = ret; - } - } - - if (rcvAll) { - if (remapKeys != null) { - assert mapErrTopVer != null; + if (err != null && + X.hasCause(err, CachePartialUpdateCheckedException.class) && + X.hasCause(err, ClusterTopologyCheckedException.class) && + storeFuture() && + --remapCnt > 0) { + ClusterTopologyCheckedException topErr = + X.cause(err, ClusterTopologyCheckedException.class); - remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); - } - else { - if (err != null && - X.hasCause(err, CachePartialUpdateCheckedException.class) && - X.hasCause(err, ClusterTopologyCheckedException.class) && - storeFuture() && - --remapCnt > 0) { - ClusterTopologyCheckedException topErr = - X.cause(err, ClusterTopologyCheckedException.class); + if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { + CachePartialUpdateCheckedException cause = + X.cause(err, CachePartialUpdateCheckedException.class); - if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { - CachePartialUpdateCheckedException cause = - X.cause(err, CachePartialUpdateCheckedException.class); + assert cause != null && cause.topologyVersion() != null : err; - assert cause != null && cause.topologyVersion() != null : err; + remapTopVer = + new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); - remapTopVer = - new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); + err = null; - err = null; + Collection failedKeys = cause.failedKeys(); - Collection failedKeys = cause.failedKeys(); + remapKeys = new ArrayList<>(failedKeys.size()); - remapKeys = new ArrayList<>(failedKeys.size()); + for (Object key : failedKeys) + remapKeys.add(cctx.toCacheKeyObject(key)); - for (Object key : failedKeys) - remapKeys.add(cctx.toCacheKeyObject(key)); - - updVer = null; - } + updVer = null; } } + } - if (remapTopVer == null) { - err0 = err; - opRes0 = opRes; - } - else { - fut0 = topCompleteFut; + if (remapTopVer == null) { + err0 = err; + opRes0 = opRes; + } + else { + fut0 = topCompleteFut; - topCompleteFut = null; + topCompleteFut = null; - cctx.mvcc().removeAtomicFuture(futVer); + cctx.mvcc().removeAtomicFuture(futVer); - futVer = null; - topVer = AffinityTopologyVersion.ZERO; - } + futVer = null; + topVer = AffinityTopologyVersion.ZERO; } } + } - if (res.error() != null && res.failedKeys() == null) { - onDone(res.error()); + if (res.error() != null && res.failedKeys() == null) { + onDone(res.error()); - return; - } + return; + } - if (rcvAll && nearEnabled) { - if (mappings != null) { - for (GridNearAtomicUpdateRequest req0 : mappings.values()) { - GridNearAtomicUpdateResponse res0 = req0.response(); + if (rcvAll && nearEnabled) { + if (mappings != null) { + for (GridNearAtomicUpdateRequest req0 : mappings.values()) { + GridNearAtomicUpdateResponse res0 = req0.response(); - assert res0 != null : req0; + assert res0 != null : req0; - updateNear(req0, res0); - } + updateNear(req0, res0); } - else if (!nodeErr) - updateNear(req, res); } + else if (!nodeErr) + updateNear(req, res); + } - if (remapTopVer != null) { - if (fut0 != null) - fut0.onDone(); + if (remapTopVer != null) { + if (fut0 != null) + fut0.onDone(); - if (!waitTopFut) { - onDone(new GridCacheTryPutFailedException()); + if (!waitTopFut) { + onDone(new GridCacheTryPutFailedException()); - return; - } + return; + } - if (topLocked) { - assert !F.isEmpty(remapKeys) : remapKeys; + if (topLocked) { + assert !F.isEmpty(remapKeys) : remapKeys; - CachePartialUpdateCheckedException e = - new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + CachePartialUpdateCheckedException e = + new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( - "Failed to update keys, topology changed while execute atomic update inside transaction."); + ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( + "Failed to update keys, topology changed while execute atomic update inside transaction."); - cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); + cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); - e.add(remapKeys, cause); + e.add(remapKeys, cause); - onDone(e); + onDone(e); - return; - } + return; + } - IgniteInternalFuture fut = - cctx.shared().exchange().affinityReadyFuture(remapTopVer); + IgniteInternalFuture fut = + cctx.shared().exchange().affinityReadyFuture(remapTopVer); - if (fut == null) - fut = new GridFinishedFuture<>(remapTopVer); + if (fut == null) + fut = new GridFinishedFuture<>(remapTopVer); - fut.listen(new CI1>() { - @Override public void apply(final IgniteInternalFuture fut) { - cctx.kernalContext().closure().runLocalSafe(new Runnable() { - @Override public void run() { - try { - AffinityTopologyVersion topVer = fut.get(); + fut.listen(new CI1>() { + @Override public void apply(final IgniteInternalFuture fut) { + cctx.kernalContext().closure().runLocalSafe(new Runnable() { + @Override public void run() { + try { + AffinityTopologyVersion topVer = fut.get(); - map(topVer, remapKeys); - } - catch (IgniteCheckedException e) { - onDone(e); - } + map(topVer, remapKeys); } - }); - } - }); - - return; - } + catch (IgniteCheckedException e) { + onDone(e); + } + } + }); + } + }); - if (rcvAll) - onDone(opRes0, err0); + return; } - /** - * @param req Request. - * @param e Error. - */ - void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { - synchronized (this) { - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); + if (rcvAll) + onDone(opRes0, err0); + } - res.addFailedKeys(req.keys(), e); + /** + * @param req Request. + * @param e Error. + */ + void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { + synchronized (this) { + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); - onResult(req.nodeId(), res, true); - } + res.addFailedKeys(req.keys(), e); + + onResult(req.nodeId(), res, true); } + } - /** - * @param topVer Topology version. - * @param remapKeys Keys to remap. - */ - void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { - Collection topNodes = CU.affinityNodes(cctx, topVer); + /** + * @param topVer Topology version. + * @param remapKeys Keys to remap. + */ + void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { + Collection topNodes = CU.affinityNodes(cctx, topVer); - if (F.isEmpty(topNodes)) { - onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid).")); + if (F.isEmpty(topNodes)) { + onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid).")); - return; - } + return; + } - Exception err = null; - GridNearAtomicUpdateRequest singleReq0 = null; - Map mappings0 = null; + Exception err = null; + GridNearAtomicUpdateRequest singleReq0 = null; + Map mappings0 = null; - int size = keys.size(); + int size = keys.size(); - GridCacheVersion futVer = cctx.versions().next(topVer); + GridCacheVersion futVer = cctx.versions().next(topVer); - GridCacheVersion updVer; + GridCacheVersion updVer; - // Assign version on near node in CLOCK ordering mode even if fastMap is false. - if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { - updVer = this.updVer; + // Assign version on near node in CLOCK ordering mode even if fastMap is false. + if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { + updVer = this.updVer; - if (updVer == null) { - updVer = cctx.versions().next(topVer); + if (updVer == null) { + updVer = cctx.versions().next(topVer); - if (log.isDebugEnabled()) - log.debug("Assigned fast-map version for update on near node: " + updVer); - } + if (log.isDebugEnabled()) + log.debug("Assigned fast-map version for update on near node: " + updVer); } - else - updVer = null; + } + else + updVer = null; - try { - if (size == 1 && !fastMap) { - assert remapKeys == null || remapKeys.size() == 1; + try { + if (size == 1 && !fastMap) { + assert remapKeys == null || remapKeys.size() == 1; - singleReq0 = mapSingleUpdate(topVer, futVer, updVer); - } + singleReq0 = mapSingleUpdate(topVer, futVer, updVer); + } + else { + Map pendingMappings = mapUpdate(topNodes, + topVer, + futVer, + updVer, + remapKeys); + + if (pendingMappings.size() == 1) + singleReq0 = F.firstValue(pendingMappings); else { - Map pendingMappings = mapUpdate(topNodes, - topVer, - futVer, - updVer, - remapKeys); + if (syncMode == PRIMARY_SYNC) { + mappings0 = U.newHashMap(pendingMappings.size()); - if (pendingMappings.size() == 1) - singleReq0 = F.firstValue(pendingMappings); - else { - if (syncMode == PRIMARY_SYNC) { - mappings0 = U.newHashMap(pendingMappings.size()); - - for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { - if (req.hasPrimary()) - mappings0.put(req.nodeId(), req); - } + for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { + if (req.hasPrimary()) + mappings0.put(req.nodeId(), req); } - else - mappings0 = pendingMappings; - - assert !mappings0.isEmpty() || size == 0 : GridNearAtomicUpdateFuture.this; } + else + mappings0 = pendingMappings; + + assert !mappings0.isEmpty() || size == 0 : this; } + } - synchronized (this) { - assert this.futVer == null : this; - assert this.topVer == AffinityTopologyVersion.ZERO : this; + synchronized (this) { + assert this.futVer == null : this; + assert this.topVer == AffinityTopologyVersion.ZERO : this; - this.topVer = topVer; - this.updVer = updVer; - this.futVer = futVer; + this.topVer = topVer; + this.updVer = updVer; + this.futVer = futVer; - resCnt = 0; + resCnt = 0; - singleReq = singleReq0; - mappings = mappings0; + singleReq = singleReq0; + mappings = mappings0; - this.remapKeys = null; - } - } - catch (Exception e) { - err = e; + this.remapKeys = null; } + } + catch (Exception e) { + err = e; + } - if (err != null) { - onDone(err); + if (err != null) { + onDone(err); - return; - } + return; + } - if (storeFuture()) { - if (!cctx.mvcc().addAtomicFuture(futVer, GridNearAtomicUpdateFuture.this)) { - assert isDone() : GridNearAtomicUpdateFuture.this; + if (storeFuture()) { + if (!cctx.mvcc().addAtomicFuture(futVer, this)) { + assert isDone() : this; - return; - } + return; } + } - // Optimize mapping for single key. - if (singleReq0 != null) - mapSingle(singleReq0.nodeId(), singleReq0); - else { - assert mappings0 != null; + // Optimize mapping for single key. + if (singleReq0 != null) + mapSingle(singleReq0.nodeId(), singleReq0); + else { + assert mappings0 != null; - if (size == 0) - onDone(new GridCacheReturn(cctx, true, true, null, true)); - else - doUpdate(mappings0); - } + if (size == 0) + onDone(new GridCacheReturn(cctx, true, true, null, true)); + else + doUpdate(mappings0); } + } - /** - * @param topVer Topology version. - * @return Future. - */ - @Nullable synchronized GridFutureAdapter completeFuture(AffinityTopologyVersion topVer) { - if (this.topVer == AffinityTopologyVersion.ZERO) - return null; - - if (this.topVer.compareTo(topVer) < 0) { - if (topCompleteFut == null) - topCompleteFut = new GridFutureAdapter<>(); + /** + * @param topVer Topology version. + * @return Future. + */ + @Nullable private synchronized GridFutureAdapter completeFuture0(AffinityTopologyVersion topVer) { + if (this.topVer == AffinityTopologyVersion.ZERO) + return null; - return topCompleteFut; - } + if (this.topVer.compareTo(topVer) < 0) { + if (topCompleteFut == null) + topCompleteFut = new GridFutureAdapter<>(); - return null; + return topCompleteFut; } - /** - * @return Future version. - */ - GridCacheVersion onFutureDone() { - GridCacheVersion ver0; - - GridFutureAdapter fut0; + return null; + } - synchronized (this) { - fut0 = topCompleteFut; + /** + * @return Future version. + */ + private GridCacheVersion onFutureDone() { + GridCacheVersion ver0; - topCompleteFut = null; + GridFutureAdapter fut0; - ver0 = futVer; + synchronized (this) { + fut0 = topCompleteFut; - futVer = null; - } + topCompleteFut = null; - if (fut0 != null) - fut0.onDone(); + ver0 = futVer; - return ver0; + futVer = null; } - /** - * @param topNodes Cache nodes. - * @param topVer Topology version. - * @param futVer Future version. - * @param updVer Update version. - * @param remapKeys Keys to remap. - * @return Mapping. - * @throws Exception If failed. - */ - private Map mapUpdate(Collection topNodes, - AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer, - @Nullable Collection remapKeys) throws Exception { - Iterator it = null; - - if (vals != null) - it = vals.iterator(); - - Iterator conflictPutValsIt = null; - - if (conflictPutVals != null) - conflictPutValsIt = conflictPutVals.iterator(); - - Iterator conflictRmvValsIt = null; - - if (conflictRmvVals != null) - conflictRmvValsIt = conflictRmvVals.iterator(); - - Map pendingMappings = U.newHashMap(topNodes.size()); - - // Create mappings first, then send messages. - for (Object key : keys) { - if (key == null) - throw new NullPointerException("Null key."); - - Object val; - GridCacheVersion conflictVer; - long conflictTtl; - long conflictExpireTime; - - if (vals != null) { - val = it.next(); - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - - if (val == null) - throw new NullPointerException("Null value."); - } - else if (conflictPutVals != null) { - GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); - - val = conflictPutVal.valueEx(); - conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); - conflictExpireTime = conflictPutVal.expireTime(); - } - else if (conflictRmvVals != null) { - val = null; - conflictVer = conflictRmvValsIt.next(); - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else { - val = null; - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - - if (val == null && op != GridCacheOperation.DELETE) - continue; - - KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + if (fut0 != null) + fut0.onDone(); - if (remapKeys != null && !remapKeys.contains(cacheKey)) - continue; + return ver0; + } - if (op != TRANSFORM) - val = cctx.toCacheObject(val); + /** + * @param topNodes Cache nodes. + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @param remapKeys Keys to remap. + * @return Mapping. + * @throws Exception If failed. + */ + private Map mapUpdate(Collection topNodes, + AffinityTopologyVersion topVer, + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer, + @Nullable Collection remapKeys) throws Exception { + Iterator it = null; - Collection affNodes = mapKey(cacheKey, topVer, fastMap); + if (vals != null) + it = vals.iterator(); - if (affNodes.isEmpty()) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); + Iterator conflictPutValsIt = null; - int i = 0; - - for (ClusterNode affNode : affNodes) { - if (affNode == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); - - UUID nodeId = affNode.id(); - - GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); - - if (mapped == null) { - mapped = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - keys.size()); - - pendingMappings.put(nodeId, mapped); - } + if (conflictPutVals != null) + conflictPutValsIt = conflictPutVals.iterator(); - mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); + Iterator conflictRmvValsIt = null; - i++; - } - } + if (conflictRmvVals != null) + conflictRmvValsIt = conflictRmvVals.iterator(); - return pendingMappings; - } + Map pendingMappings = U.newHashMap(topNodes.size()); - /** - * @param topVer Topology version. - * @param futVer Future version. - * @param updVer Update version. - * @return Request. - * @throws Exception If failed. - */ - private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer) throws Exception { - Object key = F.first(keys); + // Create mappings first, then send messages. + for (Object key : keys) { + if (key == null) + throw new NullPointerException("Null key."); Object val; GridCacheVersion conflictVer; @@ -971,127 +832,231 @@ private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topV long conflictExpireTime; if (vals != null) { - // Regular PUT. - val = F.first(vals); + val = it.next(); conflictVer = null; conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + + if (val == null) + throw new NullPointerException("Null value."); } else if (conflictPutVals != null) { - // Conflict PUT. - GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); + GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); val = conflictPutVal.valueEx(); conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); + conflictTtl = conflictPutVal.ttl(); conflictExpireTime = conflictPutVal.expireTime(); } else if (conflictRmvVals != null) { - // Conflict REMOVE. val = null; - conflictVer = F.first(conflictRmvVals); + conflictVer = conflictRmvValsIt.next(); conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; } else { - // Regular REMOVE. val = null; conflictVer = null; conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; } - // We still can get here if user pass map with single element. - if (key == null) - throw new NullPointerException("Null key."); - if (val == null && op != GridCacheOperation.DELETE) - throw new NullPointerException("Null value."); + continue; KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + if (remapKeys != null && !remapKeys.contains(cacheKey)) + continue; + if (op != TRANSFORM) val = cctx.toCacheObject(val); - ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); - - if (primary == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid)."); - - GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - true); - - return req; - } + Collection affNodes = mapKey(cacheKey, topVer, fastMap); - /** - * @param ret Result from single node. - */ - @SuppressWarnings("unchecked") - private void addInvokeResults(GridCacheReturn ret) { - assert op == TRANSFORM : op; - assert ret.value() == null || ret.value() instanceof Map : ret.value(); - - if (ret.value() != null) { - if (opRes != null) - opRes.mergeEntryProcessResults(ret); - else - opRes = ret; - } - } + if (affNodes.isEmpty()) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); + + int i = 0; - /** - * @param failedKeys Failed keys. - * @param topVer Topology version for failed update. - * @param err Error cause. - */ - private void addFailedKeys(Collection failedKeys, - AffinityTopologyVersion topVer, - Throwable err) { - CachePartialUpdateCheckedException err0 = this.err; + for (ClusterNode affNode : affNodes) { + if (affNode == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); - if (err0 == null) - err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + UUID nodeId = affNode.id(); - Collection keys = new ArrayList<>(failedKeys.size()); + GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); + + if (mapped == null) { + mapped = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + keys.size()); + + pendingMappings.put(nodeId, mapped); + } - for (KeyCacheObject key : failedKeys) - keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); + mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); - err0.add(keys, err, topVer); + i++; + } } - /** {@inheritDoc} */ - @Override public synchronized String toString() { - return S.toString(UpdateState.class, this); + return pendingMappings; + } + + /** + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @return Request. + * @throws Exception If failed. + */ + private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer) throws Exception { + Object key = F.first(keys); + + Object val; + GridCacheVersion conflictVer; + long conflictTtl; + long conflictExpireTime; + + if (vals != null) { + // Regular PUT. + val = F.first(vals); + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + else if (conflictPutVals != null) { + // Conflict PUT. + GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); + + val = conflictPutVal.valueEx(); + conflictVer = conflictPutVal.version(); + conflictTtl = conflictPutVal.ttl(); + conflictExpireTime = conflictPutVal.expireTime(); + } + else if (conflictRmvVals != null) { + // Conflict REMOVE. + val = null; + conflictVer = F.first(conflictRmvVals); + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; } + else { + // Regular REMOVE. + val = null; + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + + // We still can get here if user pass map with single element. + if (key == null) + throw new NullPointerException("Null key."); + + if (val == null && op != GridCacheOperation.DELETE) + throw new NullPointerException("Null value."); + + KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + + if (op != TRANSFORM) + val = cctx.toCacheObject(val); + + ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); + + if (primary == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid)."); + + GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; + } + + /** + * @param ret Result from single node. + */ + @SuppressWarnings("unchecked") + private void addInvokeResults(GridCacheReturn ret) { + assert op == TRANSFORM : op; + assert ret.value() == null || ret.value() instanceof Map : ret.value(); + + if (ret.value() != null) { + if (opRes != null) + opRes.mergeEntryProcessResults(ret); + else + opRes = ret; + } + } + + /** + * @param failedKeys Failed keys. + * @param topVer Topology version for failed update. + * @param err Error cause. + */ + private void addFailedKeys(Collection failedKeys, + AffinityTopologyVersion topVer, + Throwable err) { + CachePartialUpdateCheckedException err0 = this.err; + + if (err0 == null) + err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + + Collection keys = new ArrayList<>(failedKeys.size()); + + for (KeyCacheObject key : failedKeys) + keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); + + err0.add(keys, err, topVer); } /** {@inheritDoc} */ From 2a1a31d2d0999fdb8854a05fd7a75a4cd0b159a4 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 11:36:39 +0300 Subject: [PATCH 04/34] IGNITE-2532: Single update request is finalyl wired up. Though, it is not optimzied yet. --- .../GridNearAbstractAtomicUpdateFuture.java | 4 + .../atomic/GridNearAtomicUpdateFuture.java | 142 ++++++++++++------ .../atomic/GridNearAtomicUpdateRequest.java | 3 +- .../GridNearAtomicUpdateRequestInterface.java | 4 + 4 files changed, 107 insertions(+), 46 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java index 60e0c5f720462..f8c6810361327 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java @@ -34,6 +34,7 @@ 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.U; +import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; @@ -53,6 +54,9 @@ */ public abstract class GridNearAbstractAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture { + /** */ + public static final IgniteProductVersion SINGLE_PUT_MSG_SINCE = IgniteProductVersion.fromString("1.6.0"); + /** Logger reference. */ protected static final AtomicReference logRef = new AtomicReference<>(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 2aa510dc37746..493c765964fcb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -108,7 +108,7 @@ public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFutu private Collection remapKeys; /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequest singleReq; + private GridNearAtomicUpdateRequestInterface singleReq; /** Operation result. */ private GridCacheReturn opRes; @@ -195,7 +195,7 @@ public GridNearAtomicUpdateFuture( GridNearAtomicUpdateResponse res = null; synchronized (this) { - GridNearAtomicUpdateRequest req; + GridNearAtomicUpdateRequestInterface req; if (singleReq != null) req = singleReq.nodeId().equals(nodeId) ? singleReq : null; @@ -339,11 +339,11 @@ private void mapOnTopology() { * @param nodeId Node ID. * @param req Request. */ - private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { + private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -353,7 +353,13 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (log.isDebugEnabled()) log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); + if (req instanceof GridNearAtomicUpdateRequest) + cctx.io().send(req.nodeId(), (GridNearAtomicUpdateRequest)req, cctx.ioPolicy()); + else { + assert req instanceof GridNearAtomicSingleUpdateRequest; + + cctx.io().send(req.nodeId(), (GridNearAtomicSingleUpdateRequest)req, cctx.ioPolicy()); + } if (syncMode == FULL_ASYNC) onDone(new GridCacheReturn(cctx, true, true, null, true)); @@ -372,7 +378,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { private void doUpdate(Map mappings) { UUID locNodeId = cctx.localNodeId(); - GridNearAtomicUpdateRequest locUpdate = null; + GridNearAtomicUpdateRequestInterface locUpdate = null; // Send messages to remote nodes first, then run local update. for (GridNearAtomicUpdateRequest req : mappings.values()) { @@ -415,7 +421,7 @@ private void doUpdate(Map mappings) { */ @SuppressWarnings("unchecked") void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequest req; + GridNearAtomicUpdateRequestInterface req; AffinityTopologyVersion remapTopVer = null; @@ -545,7 +551,7 @@ else if (res.error() != null) { if (rcvAll && nearEnabled) { if (mappings != null) { - for (GridNearAtomicUpdateRequest req0 : mappings.values()) { + for (GridNearAtomicUpdateRequestInterface req0 : mappings.values()) { GridNearAtomicUpdateResponse res0 = req0.response(); assert res0 != null : req0; @@ -619,7 +625,7 @@ else if (!nodeErr) * @param req Request. * @param e Error. */ - void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { + void onSendError(GridNearAtomicUpdateRequestInterface req, IgniteCheckedException e) { synchronized (this) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), req.nodeId(), @@ -647,7 +653,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re } Exception err = null; - GridNearAtomicUpdateRequest singleReq0 = null; + GridNearAtomicUpdateRequestInterface singleReq0 = null; Map mappings0 = null; int size = keys.size(); @@ -674,7 +680,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re if (size == 1 && !fastMap) { assert remapKeys == null || remapKeys.size() == 1; - singleReq0 = mapSingleUpdate(topVer, futVer, updVer); + singleReq0 = mapSingleUpdate(topVer, topNodes, futVer, updVer); } else { Map pendingMappings = mapUpdate(topNodes, @@ -799,6 +805,7 @@ private GridCacheVersion onFutureDone() { * @return Mapping. * @throws Exception If failed. */ + @SuppressWarnings("ConstantConditions") private Map mapUpdate(Collection topNodes, AffinityTopologyVersion topVer, GridCacheVersion futVer, @@ -926,14 +933,14 @@ else if (conflictRmvVals != null) { /** * @param topVer Topology version. + * @param topNodes Topology nodes. * @param futVer Future version. * @param updVer Update version. * @return Request. * @throws Exception If failed. */ - private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer) throws Exception { + private GridNearAtomicUpdateRequestInterface mapSingleUpdate(AffinityTopologyVersion topVer, + Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) throws Exception { Object key = F.first(keys); Object val; @@ -990,36 +997,81 @@ else if (conflictRmvVals != null) { throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + "left the grid)."); - GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - true); - - return req; + // Decide whether we will use optimzied version of update request. + boolean optimize = true; + + for (ClusterNode topNode : topNodes) { + if (topNode.version().compareTo(SINGLE_PUT_MSG_SINCE) < 0) { + optimize = false; + + break; + } + } + + if (optimize) { + GridNearAtomicSingleUpdateRequest req = new GridNearAtomicSingleUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; + } + else { + GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; + } } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 340dbf69f11b8..674a5befc879b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -373,6 +373,7 @@ public boolean keepBinary() { * @param conflictVer Conflict version (optional). * @param primary If given key is primary on this mapping. */ + @SuppressWarnings("unchecked") public void addUpdateEntry(KeyCacheObject key, @Nullable Object val, long conflictTtl, @@ -384,7 +385,7 @@ public void addUpdateEntry(KeyCacheObject key, if (op == TRANSFORM) { assert val instanceof EntryProcessor : val; - entryProcessor = (EntryProcessor) val; + entryProcessor = (EntryProcessor)val; } assert val != null || op == DELETE; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java index 9f1775643d85d..2ef4bae22db4e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java @@ -98,4 +98,8 @@ public interface GridNearAtomicUpdateRequestInterface { public EntryProcessor entryProcessor(int idx); public CacheObject writeValue(int idx); + + @Nullable public GridNearAtomicUpdateResponse response(); + + public boolean onResponse(GridNearAtomicUpdateResponse res); } From 52d20cdcdc886c6ceaed49239e822a1d6deaa7dd Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 12:03:31 +0300 Subject: [PATCH 05/34] IGNITE-2532: WIP on single message optimization. --- .../processors/cache/GridCacheMessage.java | 49 ++++ .../GridNearAtomicSingleUpdateRequest.java | 258 ++++++------------ .../atomic/GridNearAtomicUpdateFuture.java | 6 +- 3 files changed, 137 insertions(+), 176 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java index 83e3aa71dbf1d..cdf579d787e6e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java @@ -462,6 +462,24 @@ protected final void unmarshalTx(Iterable txEntries, return args; } + /** + * @param obj Object to marshal. + * @param ctx Context. + * @return Marshalled collection. + * @throws IgniteCheckedException If failed. + */ + @Nullable protected byte[] marshal(@Nullable Object obj, GridCacheContext ctx) throws IgniteCheckedException { + assert ctx != null; + + if (obj == null) + return null; + + if (addDepInfo) + prepareObject(obj, ctx); + + return CU.marshal(ctx, obj); + } + /** * @param col Collection to marshal. * @param ctx Context. @@ -538,6 +556,19 @@ protected final void prepareMarshalCacheObjects(@Nullable Collection T unmarshal(@Nullable byte[] bytes, GridCacheSharedContext ctx, ClassLoader ldr) + throws IgniteCheckedException { + assert ldr != null; + assert ctx != null; + + if (bytes == null) + return null; + + return ctx.marshaller().unmarshal(bytes, ldr); + } + /** * @param byteCol Collection to unmarshal. * @param ctx Context. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 5de9884e00e48..cee662cc31f10 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -19,7 +19,6 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; @@ -32,7 +31,6 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.IgniteExternalizableExpiryPolicy; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.GridLongList; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; @@ -46,8 +44,8 @@ import javax.cache.processor.EntryProcessor; import java.io.Externalizable; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -91,22 +89,19 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage /** Update operation. */ private GridCacheOperation op; - /** Keys to update. */ + /** Key to update. */ @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; + private KeyCacheObject key; - /** Values to update. */ - @GridDirectCollection(CacheObject.class) - private List vals; + /** Value to update. */ + private CacheObject val; - /** Entry processors. */ + /** Entry processor. */ @GridDirectTransient - private List> entryProcessors; + private EntryProcessor entryProc; - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; + /** Entry processor bytes. */ + private byte[] entryProcBytes; /** Optional arguments for entry processor. */ @GridDirectTransient @@ -115,15 +110,14 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage /** Entry processor arguments bytes. */ private byte[][] invokeArgsBytes; - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; + /** Conflict version. */ + private GridCacheVersion conflictVer; - /** Conflict TTLs. */ - private GridLongList conflictTtls; + /** Conflict TTL. */ + private long conflictTtl = CU.TTL_NOT_CHANGED; - /** Conflict expire times. */ - private GridLongList conflictExpireTimes; + /** Conflict expire time. */ + private long conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; /** Return value flag. */ private boolean retval; @@ -138,9 +132,6 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage /** Filter. */ private CacheEntryPredicate[] filter; - /** Flag indicating whether request contains primary keys. */ - private boolean hasPrimary; - /** Subject ID. */ private UUID subjId; @@ -160,10 +151,6 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage @GridDirectTransient private GridNearAtomicUpdateResponse res; - /** Maximum possible size of inner collections. */ - @GridDirectTransient - private int initSize; - /** * Empty constructor required by {@link Externalizable}. */ @@ -193,7 +180,6 @@ public GridNearAtomicSingleUpdateRequest() { * @param keepBinary Keep binary flag. * @param clientReq Client node request flag. * @param addDepInfo Deployment info flag. - * @param maxEntryCnt Maximum entries count. */ public GridNearAtomicSingleUpdateRequest( int cacheId, @@ -214,8 +200,7 @@ public GridNearAtomicSingleUpdateRequest( boolean skipStore, boolean keepBinary, boolean clientReq, - boolean addDepInfo, - int maxEntryCnt + boolean addDepInfo ) { assert futVer != null; @@ -239,14 +224,6 @@ public GridNearAtomicSingleUpdateRequest( this.keepBinary = keepBinary; this.clientReq = clientReq; this.addDepInfo = addDepInfo; - - // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries - // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys - // participate in request. As such, we know upper bound of all collections in request. If this bound is lower - // than 10, we use it. - initSize = Math.min(maxEntryCnt, 10); - - keys = new ArrayList<>(initSize); } /** {@inheritDoc} */ @@ -372,14 +349,13 @@ public boolean keepBinary() { * @param conflictTtl Conflict TTL (optional). * @param conflictExpireTime Conflict expire time (optional). * @param conflictVer Conflict version (optional). - * @param primary If given key is primary on this mapping. */ + @SuppressWarnings("unchecked") public void addUpdateEntry(KeyCacheObject key, @Nullable Object val, long conflictTtl, long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - boolean primary) { + @Nullable GridCacheVersion conflictVer) { EntryProcessor entryProcessor = null; if (op == TRANSFORM) { @@ -390,74 +366,37 @@ public void addUpdateEntry(KeyCacheObject key, assert val != null || op == DELETE; - keys.add(key); + this.key = key; - if (entryProcessor != null) { - if (entryProcessors == null) - entryProcessors = new ArrayList<>(initSize); - - entryProcessors.add(entryProcessor); - } + if (entryProcessor != null) + this.entryProc = entryProcessor; else if (val != null) { assert val instanceof CacheObject : val; - if (vals == null) - vals = new ArrayList<>(initSize); - - vals.add((CacheObject)val); + this.val = (CacheObject)val; } - hasPrimary |= primary; + this.conflictVer = conflictVer; - // In case there is no conflict, do not create the list. - if (conflictVer != null) { - if (conflictVers == null) { - conflictVers = new ArrayList<>(initSize); - - for (int i = 0; i < keys.size() - 1; i++) - conflictVers.add(null); - } - - conflictVers.add(conflictVer); - } - else if (conflictVers != null) - conflictVers.add(null); - - if (conflictTtl >= 0) { - if (conflictTtls == null) { - conflictTtls = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictTtls.add(CU.TTL_NOT_CHANGED); - } - - conflictTtls.add(conflictTtl); - } - - if (conflictExpireTime >= 0) { - if (conflictExpireTimes == null) { - conflictExpireTimes = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } + if (conflictTtl >= 0) + this.conflictTtl = conflictTtl; - conflictExpireTimes.add(conflictExpireTime); - } + if (conflictExpireTime >= 0) + this.conflictExpireTime = conflictExpireTime; } /** * @return Keys for this update request. */ public List keys() { - return keys; + return Collections.singletonList(key); } /** * @return Values for this update request. */ public List values() { - return op == TRANSFORM ? entryProcessors : vals; + return Collections.singletonList(op == TRANSFORM ? entryProc : val); } /** @@ -480,9 +419,10 @@ public GridCacheOperation operation() { */ @SuppressWarnings("unchecked") public CacheObject value(int idx) { + assert idx == 0; assert op == UPDATE : op; - return vals.get(idx); + return val; } /** @@ -491,9 +431,10 @@ public CacheObject value(int idx) { */ @SuppressWarnings("unchecked") public EntryProcessor entryProcessor(int idx) { + assert idx == 0; assert op == TRANSFORM : op; - return entryProcessors.get(idx); + return entryProc; } /** @@ -501,17 +442,16 @@ public EntryProcessor entryProcessor(int idx) { * @return Write value - either value, or transform closure. */ public CacheObject writeValue(int idx) { - if (vals != null) - return vals.get(idx); + assert idx == 0; - return null; + return val; } /** * @return Conflict versions. */ @Nullable public List conflictVersions() { - return conflictVers; + return conflictVer == null ? null : Collections.singletonList(conflictVer); } /** @@ -519,13 +459,9 @@ public CacheObject writeValue(int idx) { * @return Conflict version. */ @Nullable public GridCacheVersion conflictVersion(int idx) { - if (conflictVers != null) { - assert idx >= 0 && idx < conflictVers.size(); - - return conflictVers.get(idx); - } + assert idx == 0; - return null; + return conflictVer; } /** @@ -533,13 +469,9 @@ public CacheObject writeValue(int idx) { * @return Conflict TTL. */ public long conflictTtl(int idx) { - if (conflictTtls != null) { - assert idx >= 0 && idx < conflictTtls.size(); + assert idx == 0; - return conflictTtls.get(idx); - } - - return CU.TTL_NOT_CHANGED; + return conflictTtl; } /** @@ -547,20 +479,16 @@ public long conflictTtl(int idx) { * @return Conflict expire time. */ public long conflictExpireTime(int idx) { - if (conflictExpireTimes != null) { - assert idx >= 0 && idx < conflictExpireTimes.size(); + assert idx == 0; - return conflictExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; + return conflictExpireTime; } /** * @return Flag indicating whether this request contains primary keys. */ public boolean hasPrimary() { - return hasPrimary; + return true; } /** @@ -591,7 +519,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { GridCacheContext cctx = ctx.cacheContext(cacheId); - prepareMarshalCacheObjects(keys, cctx); + prepareMarshalCacheObject(key, cctx); if (filter != null) { boolean hasFilter = false; @@ -616,14 +544,14 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { if (!addDepInfo && ctx.deploymentEnabled()) addDepInfo = true; - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + if (entryProcBytes == null) + entryProcBytes = marshal(entryProc, cctx); if (invokeArgsBytes == null) invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); } else - prepareMarshalCacheObjects(vals, cctx); + prepareMarshalCacheObject(val, cctx); } /** {@inheritDoc} */ @@ -632,17 +560,17 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { GridCacheContext cctx = ctx.cacheContext(cacheId); - finishUnmarshalCacheObjects(keys, cctx, ldr); + finishUnmarshalCacheObject(key, cctx, ldr); if (op == TRANSFORM) { - if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + if (entryProc == null) + entryProc = unmarshal(entryProcBytes, ctx, ldr); if (invokeArgs == null) invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); } else - finishUnmarshalCacheObjects(vals, cctx, ldr); + finishUnmarshalCacheObject(val, cctx, ldr); if (filter != null) { for (CacheEntryPredicate p : filter) { @@ -682,25 +610,25 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { writer.incrementState(); case 4: - if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) + if (!writer.writeLong("conflictExpireTime", conflictExpireTime)) return false; writer.incrementState(); case 5: - if (!writer.writeMessage("conflictTtls", conflictTtls)) + if (!writer.writeLong("conflictTtl", conflictTtl)) return false; writer.incrementState(); case 6: - if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + if (!writer.writeMessage("conflictVer", conflictVer)) return false; writer.incrementState(); case 7: - if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + if (!writer.writeByteArray("entryProcBytes", entryProcBytes)) return false; writer.incrementState(); @@ -730,85 +658,79 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { writer.incrementState(); case 12: - if (!writer.writeBoolean("hasPrimary", hasPrimary)) + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) return false; writer.incrementState(); case 13: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + if (!writer.writeBoolean("keepBinary", keepBinary)) return false; writer.incrementState(); case 14: - if (!writer.writeBoolean("keepBinary", keepBinary)) + if (!writer.writeMessage("key", key)) return false; writer.incrementState(); case 15: - if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 16: if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) return false; writer.incrementState(); - case 17: + case 16: if (!writer.writeBoolean("retval", retval)) return false; writer.incrementState(); - case 18: + case 17: if (!writer.writeBoolean("skipStore", skipStore)) return false; writer.incrementState(); - case 19: + case 18: if (!writer.writeUuid("subjId", subjId)) return false; writer.incrementState(); - case 20: + case 19: if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) return false; writer.incrementState(); - case 21: + case 20: if (!writer.writeInt("taskNameHash", taskNameHash)) return false; writer.incrementState(); - case 22: + case 21: if (!writer.writeBoolean("topLocked", topLocked)) return false; writer.incrementState(); - case 23: + case 22: if (!writer.writeMessage("topVer", topVer)) return false; writer.incrementState(); - case 24: + case 23: if (!writer.writeMessage("updateVer", updateVer)) return false; writer.incrementState(); - case 25: - if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + case 24: + if (!writer.writeMessage("val", val)) return false; writer.incrementState(); @@ -838,7 +760,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 4: - conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + conflictExpireTime = reader.readLong("conflictExpireTime"); if (!reader.isLastRead()) return false; @@ -846,7 +768,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 5: - conflictTtls = reader.readMessage("conflictTtls"); + conflictTtl = reader.readLong("conflictTtl"); if (!reader.isLastRead()) return false; @@ -854,7 +776,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 6: - conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + conflictVer = reader.readMessage("conflictVer"); if (!reader.isLastRead()) return false; @@ -862,7 +784,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 7: - entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + entryProcBytes = reader.readByteArray("entryProcBytes"); if (!reader.isLastRead()) return false; @@ -902,7 +824,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 12: - hasPrimary = reader.readBoolean("hasPrimary"); + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); if (!reader.isLastRead()) return false; @@ -910,7 +832,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 13: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + keepBinary = reader.readBoolean("keepBinary"); if (!reader.isLastRead()) return false; @@ -918,7 +840,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 14: - keepBinary = reader.readBoolean("keepBinary"); + key = reader.readMessage("key"); if (!reader.isLastRead()) return false; @@ -926,14 +848,6 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); case 15: - keys = reader.readCollection("keys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 16: byte opOrd; opOrd = reader.readByte("op"); @@ -945,7 +859,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 17: + case 16: retval = reader.readBoolean("retval"); if (!reader.isLastRead()) @@ -953,7 +867,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 18: + case 17: skipStore = reader.readBoolean("skipStore"); if (!reader.isLastRead()) @@ -961,7 +875,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 19: + case 18: subjId = reader.readUuid("subjId"); if (!reader.isLastRead()) @@ -969,7 +883,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 20: + case 19: byte syncModeOrd; syncModeOrd = reader.readByte("syncMode"); @@ -981,7 +895,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 21: + case 20: taskNameHash = reader.readInt("taskNameHash"); if (!reader.isLastRead()) @@ -989,7 +903,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 22: + case 21: topLocked = reader.readBoolean("topLocked"); if (!reader.isLastRead()) @@ -997,7 +911,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 23: + case 22: topVer = reader.readMessage("topVer"); if (!reader.isLastRead()) @@ -1005,7 +919,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 24: + case 23: updateVer = reader.readMessage("updateVer"); if (!reader.isLastRead()) @@ -1013,8 +927,8 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { reader.incrementState(); - case 25: - vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + case 24: + val = reader.readMessage("val"); if (!reader.isLastRead()) return false; @@ -1033,7 +947,7 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { /** {@inheritDoc} */ @Override public byte fieldsCount() { - return 26; + return 25; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 493c765964fcb..38e93ecdea1a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -1028,15 +1028,13 @@ else if (conflictRmvVals != null) { skipStore, keepBinary, cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); + cctx.deploymentEnabled()); req.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, - conflictVer, - true); + conflictVer); return req; } From 89c8074452b4bc209eb03d758e534f0ef8365d46 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 12:08:18 +0300 Subject: [PATCH 06/34] IGNITE-2532: WIP on single message optimization. --- .../GridNearAtomicSingleUpdateRequest.java | 81 +++++++++---------- .../atomic/GridNearAtomicUpdateFuture.java | 15 ++-- 2 files changed, 45 insertions(+), 51 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index cee662cc31f10..9ef0b6c612289 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -161,6 +161,11 @@ public GridNearAtomicSingleUpdateRequest() { /** * Constructor. * + * @param key Key. + * @param val Value. + * @param conflictTtl Conflict TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). * @param cacheId Cache ID. * @param nodeId Node ID. * @param futVer Future version. @@ -181,7 +186,13 @@ public GridNearAtomicSingleUpdateRequest() { * @param clientReq Client node request flag. * @param addDepInfo Deployment info flag. */ + @SuppressWarnings("unchecked") public GridNearAtomicSingleUpdateRequest( + KeyCacheObject key, + @Nullable Object val, + long conflictTtl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, int cacheId, UUID nodeId, GridCacheVersion futVer, @@ -204,6 +215,8 @@ public GridNearAtomicSingleUpdateRequest( ) { assert futVer != null; + this.key = key; + this.cacheId = cacheId; this.nodeId = nodeId; this.futVer = futVer; @@ -224,6 +237,32 @@ public GridNearAtomicSingleUpdateRequest( this.keepBinary = keepBinary; this.clientReq = clientReq; this.addDepInfo = addDepInfo; + + EntryProcessor entryProc = null; + + if (op == TRANSFORM) { + assert val instanceof EntryProcessor : val; + + entryProc = (EntryProcessor) val; + } + + assert val != null || op == DELETE; + + if (entryProc != null) + this.entryProc = entryProc; + else if (val != null) { + assert val instanceof CacheObject : val; + + this.val = (CacheObject)val; + } + + this.conflictVer = conflictVer; + + if (conflictTtl >= 0) + this.conflictTtl = conflictTtl; + + if (conflictExpireTime >= 0) + this.conflictExpireTime = conflictExpireTime; } /** {@inheritDoc} */ @@ -343,48 +382,6 @@ public boolean keepBinary() { return keepBinary; } - /** - * @param key Key to add. - * @param val Optional update value. - * @param conflictTtl Conflict TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - */ - @SuppressWarnings("unchecked") - public void addUpdateEntry(KeyCacheObject key, - @Nullable Object val, - long conflictTtl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer) { - EntryProcessor entryProcessor = null; - - if (op == TRANSFORM) { - assert val instanceof EntryProcessor : val; - - entryProcessor = (EntryProcessor) val; - } - - assert val != null || op == DELETE; - - this.key = key; - - if (entryProcessor != null) - this.entryProc = entryProcessor; - else if (val != null) { - assert val instanceof CacheObject : val; - - this.val = (CacheObject)val; - } - - this.conflictVer = conflictVer; - - if (conflictTtl >= 0) - this.conflictTtl = conflictTtl; - - if (conflictExpireTime >= 0) - this.conflictExpireTime = conflictExpireTime; - } - /** * @return Keys for this update request. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 38e93ecdea1a4..c8550f3aaf7dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -1009,7 +1009,12 @@ else if (conflictRmvVals != null) { } if (optimize) { - GridNearAtomicSingleUpdateRequest req = new GridNearAtomicSingleUpdateRequest( + return new GridNearAtomicSingleUpdateRequest( + cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, cctx.cacheId(), primary.id(), futVer, @@ -1029,14 +1034,6 @@ else if (conflictRmvVals != null) { keepBinary, cctx.kernalContext().clientNode(), cctx.deploymentEnabled()); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer); - - return req; } else { GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( From 07c23931f9758497db50bf0851af5d6c0fb8eaa4 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 12:45:42 +0300 Subject: [PATCH 07/34] IGNITE-2532: Reverting changes to GridNearAtomicUpdateFuture. --- .../GridNearAbstractAtomicUpdateFuture.java | 252 --- .../atomic/GridNearAtomicUpdateFuture.java | 1400 ++++++++++------- 2 files changed, 798 insertions(+), 854 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java deleted file mode 100644 index f8c6810361327..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAbstractAtomicUpdateFuture.java +++ /dev/null @@ -1,252 +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.atomic; - -import org.apache.ignite.IgniteLogger; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; -import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; -import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.KeyCacheObject; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; -import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.future.GridFutureAdapter; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteProductVersion; -import org.apache.ignite.lang.IgniteUuid; -import org.jetbrains.annotations.Nullable; - -import javax.cache.expiry.ExpiryPolicy; -import java.util.Collection; -import java.util.Collections; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - -import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; -import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; - -/** - * Base class for near atomic update futures. - */ -public abstract class GridNearAbstractAtomicUpdateFuture extends GridFutureAdapter - implements GridCacheAtomicFuture { - /** */ - public static final IgniteProductVersion SINGLE_PUT_MSG_SINCE = IgniteProductVersion.fromString("1.6.0"); - - /** Logger reference. */ - protected static final AtomicReference logRef = new AtomicReference<>(); - - /** Logger. */ - protected static IgniteLogger log; - - /** Optional arguments for entry processor. */ - protected Object[] invokeArgs; - - /** Cache context. */ - protected final GridCacheContext cctx; - - /** Cache. */ - protected final GridDhtAtomicCache cache; - - /** Update operation. */ - protected final GridCacheOperation op; - - /** Return value require flag. */ - protected final boolean retval; - - /** Expiry policy. */ - protected final ExpiryPolicy expiryPlc; - - /** Optional filter. */ - protected final CacheEntryPredicate[] filter; - - /** Write synchronization mode. */ - protected final CacheWriteSynchronizationMode syncMode; - - /** Raw return value flag. */ - protected final boolean rawRetval; - - /** Fast map flag. */ - protected final boolean fastMap; - - /** Near cache flag. */ - protected final boolean nearEnabled; - - /** Subject ID. */ - protected final UUID subjId; - - /** Task name hash. */ - protected final int taskNameHash; - - /** Skip store flag. */ - protected final boolean skipStore; - - /** */ - protected final boolean keepBinary; - - /** Wait for topology future flag. */ - protected final boolean waitTopFut; - - /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ - protected boolean topLocked; - - /** Remap count. */ - protected int remapCnt; - - /** - * @param cctx Cache context. - * @param cache Cache instance. - * @param syncMode Write synchronization mode. - * @param op Update operation. - * @param invokeArgs Optional arguments for entry processor. - * @param retval Return value require flag. - * @param rawRetval {@code True} if should return {@code GridCacheReturn} as future result. - * @param expiryPlc Expiry policy explicitly specified for cache operation. - * @param filter Entry filter. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param skipStore Skip store flag. - * @param keepBinary Keep binary flag. - * @param remapCnt Maximum number of retries. - * @param waitTopFut If {@code false} does not wait for affinity change future. - */ - public GridNearAbstractAtomicUpdateFuture( - GridCacheContext cctx, - GridDhtAtomicCache cache, - CacheWriteSynchronizationMode syncMode, - GridCacheOperation op, - @Nullable Object[] invokeArgs, - final boolean retval, - final boolean rawRetval, - @Nullable ExpiryPolicy expiryPlc, - final CacheEntryPredicate[] filter, - UUID subjId, - int taskNameHash, - boolean skipStore, - boolean keepBinary, - int remapCnt, - boolean waitTopFut - ) { - this.rawRetval = rawRetval; - - assert subjId != null; - - this.cctx = cctx; - this.cache = cache; - this.syncMode = syncMode; - this.op = op; - this.invokeArgs = invokeArgs; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.waitTopFut = waitTopFut; - - if (log == null) - log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); - - fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && - cctx.config().getAtomicWriteOrderMode() == CLOCK && - !(cctx.writeThrough() && cctx.config().getInterceptor() != null); - - nearEnabled = CU.isNearEnabled(cctx); - - if (!waitTopFut) - remapCnt = 1; - - this.remapCnt = remapCnt; - } - - /** {@inheritDoc} */ - @Override public IgniteUuid futureId() { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override public boolean trackable() { - return true; - } - - /** {@inheritDoc} */ - @Override public void markNotTrackable() { - // No-op. - } - - /** - * @return {@code True} if this future should block partition map exchange. - */ - protected boolean waitForPartitionExchange() { - // Wait fast-map near atomic update futures in CLOCK mode. - return fastMap; - } - - /** - * Updates near cache. - * - * @param req Update request. - * @param res Update response. - */ - protected void updateNear(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { - assert nearEnabled; - - if (res.remapKeys() != null || !req.hasPrimary()) - return; - - GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); - - near.processNearAtomicUpdateResponse(req, res); - } - - /** - * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. - */ - protected boolean storeFuture() { - return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; - } - - /** - * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near - * node and send updates in parallel to all participating nodes. - * - * @param key Key to map. - * @param topVer Topology version to map. - * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. - * @return Collection of nodes to which key is mapped. - */ - protected Collection mapKey(KeyCacheObject key, AffinityTopologyVersion topVer, boolean fastMap - ) { - GridCacheAffinityManager affMgr = cctx.affinity(); - - // If we can send updates in parallel - do it. - return fastMap ? - cctx.topology().nodes(affMgr.partition(key), topVer) : - Collections.singletonList(affMgr.primary(key, topVer)); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index c8550f3aaf7dc..149d277d39624 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -17,7 +17,16 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import javax.cache.expiry.ExpiryPolicy; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteLogger; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -26,12 +35,16 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException; +import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; +import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.GridCacheTryPutFailedException; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.future.GridFinishedFuture; @@ -44,26 +57,38 @@ 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.IgniteProductVersion; +import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; -import javax.cache.expiry.ExpiryPolicy; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.UUID; - import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC; import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; /** * DHT atomic cache near update future. */ -@SuppressWarnings("ThrowableResultOfMethodCallIgnored") -public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFuture { +public class GridNearAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture{ + /** Version where single-put optimization appeared.*/ + public static final IgniteProductVersion SINGLE_PUT_MSG_SINCE = IgniteProductVersion.fromString("1.6.0"); + + /** Logger reference. */ + private static final AtomicReference logRef = new AtomicReference<>(); + + /** Logger. */ + protected static IgniteLogger log; + + /** Cache context. */ + private final GridCacheContext cctx; + + /** Cache. */ + private GridDhtAtomicCache cache; + + /** Update operation. */ + private final GridCacheOperation op; + /** Keys */ private Collection keys; @@ -71,6 +96,9 @@ public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFutu @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection vals; + /** Optional arguments for entry processor. */ + private Object[] invokeArgs; + /** Conflict put values. */ @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection conflictPutVals; @@ -79,39 +107,50 @@ public class GridNearAtomicUpdateFuture extends GridNearAbstractAtomicUpdateFutu @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection conflictRmvVals; - /** Current topology version. */ - private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; + /** Return value require flag. */ + private final boolean retval; - /** */ - private GridCacheVersion updVer; + /** Expiry policy. */ + private final ExpiryPolicy expiryPlc; - /** Topology version when got mapping error. */ - private AffinityTopologyVersion mapErrTopVer; + /** Optional filter. */ + private final CacheEntryPredicate[] filter; - /** Mappings if operations is mapped to more than one node. */ - @GridToStringInclude - private Map mappings; + /** Write synchronization mode. */ + private final CacheWriteSynchronizationMode syncMode; - /** */ - private int resCnt; + /** Raw return value flag. */ + private final boolean rawRetval; + + /** Fast map flag. */ + private final boolean fastMap; + + /** Near cache flag. */ + private final boolean nearEnabled; - /** Error. */ - private CachePartialUpdateCheckedException err; + /** Subject ID. */ + private final UUID subjId; - /** Future ID. */ - private GridCacheVersion futVer; + /** Task name hash. */ + private final int taskNameHash; - /** Completion future for a particular topology version. */ - private GridFutureAdapter topCompleteFut; + /** Topology locked flag. Set if atomic update is performed inside a TX or explicit lock. */ + private boolean topLocked; + + /** Skip store flag. */ + private final boolean skipStore; + + /** */ + private final boolean keepBinary; - /** Keys to remap. */ - private Collection remapKeys; + /** Wait for topology future flag. */ + private final boolean waitTopFut; - /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequestInterface singleReq; + /** Remap count. */ + private int remapCnt; - /** Operation result. */ - private GridCacheReturn opRes; + /** State. */ + private final UpdateState state; /** * @param cctx Cache context. @@ -155,72 +194,116 @@ public GridNearAtomicUpdateFuture( int remapCnt, boolean waitTopFut ) { - super(cctx, cache, syncMode, op, invokeArgs, retval, rawRetval, expiryPlc, filter, subjId, taskNameHash, - skipStore, keepBinary, remapCnt, waitTopFut); + this.rawRetval = rawRetval; assert vals == null || vals.size() == keys.size(); assert conflictPutVals == null || conflictPutVals.size() == keys.size(); assert conflictRmvVals == null || conflictRmvVals.size() == keys.size(); + assert subjId != null; + this.cctx = cctx; + this.cache = cache; + this.syncMode = syncMode; + this.op = op; this.keys = keys; this.vals = vals; + this.invokeArgs = invokeArgs; this.conflictPutVals = conflictPutVals; this.conflictRmvVals = conflictRmvVals; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.waitTopFut = waitTopFut; + + if (log == null) + log = U.logger(cctx.kernalContext(), logRef, GridFutureAdapter.class); + + fastMap = F.isEmpty(filter) && op != TRANSFORM && cctx.config().getWriteSynchronizationMode() == FULL_SYNC && + cctx.config().getAtomicWriteOrderMode() == CLOCK && + !(cctx.writeThrough() && cctx.config().getInterceptor() != null); + + nearEnabled = CU.isNearEnabled(cctx); + + if (!waitTopFut) + remapCnt = 1; + + this.remapCnt = remapCnt; + + state = new UpdateState(); } /** {@inheritDoc} */ - @Override public synchronized GridCacheVersion version() { - return futVer; + @Override public IgniteUuid futureId() { + throw new UnsupportedOperationException(); } /** {@inheritDoc} */ - @Override public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer) { - if (waitForPartitionExchange()) { - GridFutureAdapter fut = completeFuture0(topVer); + @Override public GridCacheVersion version() { + return state.futureVersion(); + } - if (fut != null && isDone()) { - fut.onDone(); + /** + * @return {@code True} if this future should block partition map exchange. + */ + private boolean waitForPartitionExchange() { + // Wait fast-map near atomic update futures in CLOCK mode. + return fastMap; + } - return null; - } + /** {@inheritDoc} */ + @Override public boolean onNodeLeft(UUID nodeId) { + state.onNodeLeft(nodeId); - return fut; - } + return false; + } - return null; + /** {@inheritDoc} */ + @Override public boolean trackable() { + return true; } /** {@inheritDoc} */ - @Override public boolean onNodeLeft(UUID nodeId) { - GridNearAtomicUpdateResponse res = null; + @Override public void markNotTrackable() { + // No-op. + } - synchronized (this) { - GridNearAtomicUpdateRequestInterface req; + /** + * Performs future mapping. + */ + public void map() { + AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); - if (singleReq != null) - req = singleReq.nodeId().equals(nodeId) ? singleReq : null; - else - req = mappings != null ? mappings.get(nodeId) : null; + if (topVer == null) + mapOnTopology(); + else { + topLocked = true; - if (req != null && req.response() == null) { - res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); + // Cannot remap. + remapCnt = 1; - ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + - "before response is received: " + nodeId); + state.map(topVer, null); + } + } - e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); + /** {@inheritDoc} */ + @Override public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer) { + if (waitForPartitionExchange()) { + GridFutureAdapter fut = state.completeFuture(topVer); - res.addFailedKeys(req.keys(), e); + if (fut != null && isDone()) { + fut.onDone(); + + return null; } - } - if (res != null) - onResult(nodeId, res, true); + return fut; + } - return false; + return null; } /** {@inheritDoc} */ @@ -238,7 +321,7 @@ public GridNearAtomicUpdateFuture( retval = Collections.emptyMap(); if (super.onDone(retval, err)) { - GridCacheVersion futVer = onFutureDone(); + GridCacheVersion futVer = state.onFutureDone(); if (futVer != null) cctx.mvcc().removeAtomicFuture(futVer); @@ -250,31 +333,30 @@ public GridNearAtomicUpdateFuture( } /** - * Performs future mapping. + * Response callback. + * + * @param nodeId Node ID. + * @param res Update response. */ - public void map() { - AffinityTopologyVersion topVer = cctx.shared().lockedTopologyVersion(null); - - if (topVer == null) - mapOnTopology(); - else { - topLocked = true; - - // Cannot remap. - remapCnt = 1; - - map(topVer, null); - } + public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { + state.onResult(nodeId, res, false); } /** - * Response callback. + * Updates near cache. * - * @param nodeId Node ID. + * @param req Update request. * @param res Update response. */ - public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { - onResult(nodeId, res, false); + private void updateNear(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { + assert nearEnabled; + + if (res.remapKeys() != null || !req.hasPrimary()) + return; + + GridNearAtomicCache near = (GridNearAtomicCache)cctx.dht().near(); + + near.processNearAtomicUpdateResponse(req, res); } /** @@ -330,7 +412,36 @@ private void mapOnTopology() { cache.topology().readUnlock(); } - map(topVer, null); + state.map(topVer, null); + } + + /** + * @return {@code True} future is stored by {@link GridCacheMvccManager#addAtomicFuture}. + */ + private boolean storeFuture() { + return cctx.config().getAtomicWriteOrderMode() == CLOCK || syncMode != FULL_ASYNC; + } + + /** + * Maps key to nodes. If filters are absent and operation is not TRANSFORM, then we can assign version on near + * node and send updates in parallel to all participating nodes. + * + * @param key Key to map. + * @param topVer Topology version to map. + * @param fastMap Flag indicating whether mapping is performed for fast-circuit update. + * @return Collection of nodes to which key is mapped. + */ + private Collection mapKey( + KeyCacheObject key, + AffinityTopologyVersion topVer, + boolean fastMap + ) { + GridCacheAffinityManager affMgr = cctx.affinity(); + + // If we can send updates in parallel - do it. + return fastMap ? + cctx.topology().nodes(affMgr.partition(key), topVer) : + Collections.singletonList(affMgr.primary(key, topVer)); } /** @@ -343,7 +454,8 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, new CI2() { - @Override public void apply(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequestInterface req, + GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -365,7 +477,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { onDone(new GridCacheReturn(cctx, true, true, null, true)); } catch (IgniteCheckedException e) { - onSendError(req, e); + state.onSendError(req, e); } } } @@ -378,7 +490,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { private void doUpdate(Map mappings) { UUID locNodeId = cctx.localNodeId(); - GridNearAtomicUpdateRequestInterface locUpdate = null; + GridNearAtomicUpdateRequest locUpdate = null; // Send messages to remote nodes first, then run local update. for (GridNearAtomicUpdateRequest req : mappings.values()) { @@ -396,7 +508,7 @@ private void doUpdate(Map mappings) { cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); } catch (IgniteCheckedException e) { - onSendError(req, e); + state.onSendError(req, e); } } } @@ -415,423 +527,611 @@ private void doUpdate(Map mappings) { } /** - * @param nodeId Node ID. - * @param res Response. - * @param nodeErr {@code True} if response was created on node failure. + * */ - @SuppressWarnings("unchecked") - void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequestInterface req; + private class UpdateState { + /** Current topology version. */ + private AffinityTopologyVersion topVer = AffinityTopologyVersion.ZERO; - AffinityTopologyVersion remapTopVer = null; + /** */ + private GridCacheVersion updVer; - GridCacheReturn opRes0 = null; - CachePartialUpdateCheckedException err0 = null; + /** Topology version when got mapping error. */ + private AffinityTopologyVersion mapErrTopVer; - boolean rcvAll; + /** Mappings if operations is mapped to more than one node. */ + @GridToStringInclude + private Map mappings; - GridFutureAdapter fut0 = null; + /** */ + private int resCnt; - synchronized (this) { - if (!res.futureVersion().equals(futVer)) - return; + /** Error. */ + private CachePartialUpdateCheckedException err; - if (singleReq != null) { - if (!singleReq.nodeId().equals(nodeId)) - return; + /** Future ID. */ + private GridCacheVersion futVer; - req = singleReq; + /** Completion future for a particular topology version. */ + private GridFutureAdapter topCompleteFut; - singleReq = null; + /** Keys to remap. */ + private Collection remapKeys; - rcvAll = true; - } - else { - req = mappings != null ? mappings.get(nodeId) : null; + /** Not null is operation is mapped to single node. */ + private GridNearAtomicUpdateRequestInterface singleReq; - if (req != null && req.onResponse(res)) { - resCnt++; + /** Operation result. */ + private GridCacheReturn opRes; - rcvAll = mappings.size() == resCnt; - } + /** + * @return Future version. + */ + @Nullable synchronized GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @param nodeId Left node ID. + */ + void onNodeLeft(UUID nodeId) { + GridNearAtomicUpdateResponse res = null; + + synchronized (this) { + GridNearAtomicUpdateRequestInterface req; + + if (singleReq != null) + req = singleReq.nodeId().equals(nodeId) ? singleReq : null; else - return; + req = mappings != null ? mappings.get(nodeId) : null; + + if (req != null && req.response() == null) { + res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); + + ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + + "before response is received: " + nodeId); + + e.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(req.topologyVersion())); + + res.addFailedKeys(req.keys(), e); + } } - assert req != null && req.topologyVersion().equals(topVer) : req; + if (res != null) + onResult(nodeId, res, true); + } - if (res.remapKeys() != null) { - assert !fastMap || cctx.kernalContext().clientNode(); + /** + * @param nodeId Node ID. + * @param res Response. + * @param nodeErr {@code True} if response was created on node failure. + */ + @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) + void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { + GridNearAtomicUpdateRequestInterface req; - if (remapKeys == null) - remapKeys = U.newHashSet(res.remapKeys().size()); + AffinityTopologyVersion remapTopVer = null; - remapKeys.addAll(res.remapKeys()); + GridCacheReturn opRes0 = null; + CachePartialUpdateCheckedException err0 = null; - if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) - mapErrTopVer = req.topologyVersion(); - } - else if (res.error() != null) { - if (res.failedKeys() != null) - addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); - } - else { - if (!req.fastMap() || req.hasPrimary()) { - GridCacheReturn ret = res.returnValue(); + boolean rcvAll; + + GridFutureAdapter fut0 = null; + + synchronized (this) { + if (!res.futureVersion().equals(futVer)) + return; + + if (singleReq != null) { + if (!singleReq.nodeId().equals(nodeId)) + return; + + req = singleReq; + + singleReq = null; + + rcvAll = true; + } + else { + req = mappings != null ? mappings.get(nodeId) : null; + + if (req != null && req.onResponse(res)) { + resCnt++; - if (op == TRANSFORM) { - if (ret != null) - addInvokeResults(ret); + rcvAll = mappings.size() == resCnt; } else - opRes = ret; + return; } - } - if (rcvAll) { - if (remapKeys != null) { - assert mapErrTopVer != null; + assert req != null && req.topologyVersion().equals(topVer) : req; + + if (res.remapKeys() != null) { + assert !fastMap || cctx.kernalContext().clientNode(); + + if (remapKeys == null) + remapKeys = U.newHashSet(res.remapKeys().size()); - remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); + remapKeys.addAll(res.remapKeys()); + + if (mapErrTopVer == null || mapErrTopVer.compareTo(req.topologyVersion()) < 0) + mapErrTopVer = req.topologyVersion(); + } + else if (res.error() != null) { + if (res.failedKeys() != null) + addFailedKeys(res.failedKeys(), req.topologyVersion(), res.error()); } else { - if (err != null && - X.hasCause(err, CachePartialUpdateCheckedException.class) && - X.hasCause(err, ClusterTopologyCheckedException.class) && - storeFuture() && - --remapCnt > 0) { - ClusterTopologyCheckedException topErr = - X.cause(err, ClusterTopologyCheckedException.class); + if (!req.fastMap() || req.hasPrimary()) { + GridCacheReturn ret = res.returnValue(); + + if (op == TRANSFORM) { + if (ret != null) + addInvokeResults(ret); + } + else + opRes = ret; + } + } + + if (rcvAll) { + if (remapKeys != null) { + assert mapErrTopVer != null; + + remapTopVer = new AffinityTopologyVersion(mapErrTopVer.topologyVersion() + 1); + } + else { + if (err != null && + X.hasCause(err, CachePartialUpdateCheckedException.class) && + X.hasCause(err, ClusterTopologyCheckedException.class) && + storeFuture() && + --remapCnt > 0) { + ClusterTopologyCheckedException topErr = + X.cause(err, ClusterTopologyCheckedException.class); - if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { - CachePartialUpdateCheckedException cause = - X.cause(err, CachePartialUpdateCheckedException.class); + if (!(topErr instanceof ClusterTopologyServerNotFoundException)) { + CachePartialUpdateCheckedException cause = + X.cause(err, CachePartialUpdateCheckedException.class); - assert cause != null && cause.topologyVersion() != null : err; + assert cause != null && cause.topologyVersion() != null : err; - remapTopVer = - new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); + remapTopVer = + new AffinityTopologyVersion(cause.topologyVersion().topologyVersion() + 1); - err = null; + err = null; - Collection failedKeys = cause.failedKeys(); + Collection failedKeys = cause.failedKeys(); - remapKeys = new ArrayList<>(failedKeys.size()); + remapKeys = new ArrayList<>(failedKeys.size()); - for (Object key : failedKeys) - remapKeys.add(cctx.toCacheKeyObject(key)); + for (Object key : failedKeys) + remapKeys.add(cctx.toCacheKeyObject(key)); - updVer = null; + updVer = null; + } } } - } - if (remapTopVer == null) { - err0 = err; - opRes0 = opRes; - } - else { - fut0 = topCompleteFut; + if (remapTopVer == null) { + err0 = err; + opRes0 = opRes; + } + else { + fut0 = topCompleteFut; - topCompleteFut = null; + topCompleteFut = null; - cctx.mvcc().removeAtomicFuture(futVer); + cctx.mvcc().removeAtomicFuture(futVer); - futVer = null; - topVer = AffinityTopologyVersion.ZERO; + futVer = null; + topVer = AffinityTopologyVersion.ZERO; + } } } - } - if (res.error() != null && res.failedKeys() == null) { - onDone(res.error()); + if (res.error() != null && res.failedKeys() == null) { + onDone(res.error()); - return; - } + return; + } - if (rcvAll && nearEnabled) { - if (mappings != null) { - for (GridNearAtomicUpdateRequestInterface req0 : mappings.values()) { - GridNearAtomicUpdateResponse res0 = req0.response(); + if (rcvAll && nearEnabled) { + if (mappings != null) { + for (GridNearAtomicUpdateRequest req0 : mappings.values()) { + GridNearAtomicUpdateResponse res0 = req0.response(); - assert res0 != null : req0; + assert res0 != null : req0; - updateNear(req0, res0); + updateNear(req0, res0); + } } + else if (!nodeErr) + updateNear(req, res); } - else if (!nodeErr) - updateNear(req, res); - } - if (remapTopVer != null) { - if (fut0 != null) - fut0.onDone(); + if (remapTopVer != null) { + if (fut0 != null) + fut0.onDone(); - if (!waitTopFut) { - onDone(new GridCacheTryPutFailedException()); + if (!waitTopFut) { + onDone(new GridCacheTryPutFailedException()); - return; - } + return; + } - if (topLocked) { - assert !F.isEmpty(remapKeys) : remapKeys; + if (topLocked) { + assert !F.isEmpty(remapKeys) : remapKeys; - CachePartialUpdateCheckedException e = - new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); + CachePartialUpdateCheckedException e = + new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( - "Failed to update keys, topology changed while execute atomic update inside transaction."); + ClusterTopologyCheckedException cause = new ClusterTopologyCheckedException( + "Failed to update keys, topology changed while execute atomic update inside transaction."); - cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); + cause.retryReadyFuture(cctx.affinity().affinityReadyFuture(remapTopVer)); - e.add(remapKeys, cause); + e.add(remapKeys, cause); - onDone(e); + onDone(e); - return; - } + return; + } - IgniteInternalFuture fut = - cctx.shared().exchange().affinityReadyFuture(remapTopVer); + IgniteInternalFuture fut = + cctx.shared().exchange().affinityReadyFuture(remapTopVer); - if (fut == null) - fut = new GridFinishedFuture<>(remapTopVer); + if (fut == null) + fut = new GridFinishedFuture<>(remapTopVer); - fut.listen(new CI1>() { - @Override public void apply(final IgniteInternalFuture fut) { - cctx.kernalContext().closure().runLocalSafe(new Runnable() { - @Override public void run() { - try { - AffinityTopologyVersion topVer = fut.get(); + fut.listen(new CI1>() { + @Override public void apply(final IgniteInternalFuture fut) { + cctx.kernalContext().closure().runLocalSafe(new Runnable() { + @Override public void run() { + try { + AffinityTopologyVersion topVer = fut.get(); - map(topVer, remapKeys); - } - catch (IgniteCheckedException e) { - onDone(e); + map(topVer, remapKeys); + } + catch (IgniteCheckedException e) { + onDone(e); + } } - } - }); - } - }); + }); + } + }); - return; - } + return; + } - if (rcvAll) - onDone(opRes0, err0); - } + if (rcvAll) + onDone(opRes0, err0); + } - /** - * @param req Request. - * @param e Error. - */ - void onSendError(GridNearAtomicUpdateRequestInterface req, IgniteCheckedException e) { - synchronized (this) { - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); + /** + * @param req Request. + * @param e Error. + */ + void onSendError(GridNearAtomicUpdateRequestInterface req, IgniteCheckedException e) { + synchronized (this) { + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); - res.addFailedKeys(req.keys(), e); + res.addFailedKeys(req.keys(), e); - onResult(req.nodeId(), res, true); + onResult(req.nodeId(), res, true); + } } - } - /** - * @param topVer Topology version. - * @param remapKeys Keys to remap. - */ - void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { - Collection topNodes = CU.affinityNodes(cctx, topVer); + /** + * @param topVer Topology version. + * @param remapKeys Keys to remap. + */ + void map(AffinityTopologyVersion topVer, @Nullable Collection remapKeys) { + Collection topNodes = CU.affinityNodes(cctx, topVer); - if (F.isEmpty(topNodes)) { - onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid).")); + if (F.isEmpty(topNodes)) { + onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid).")); - return; - } + return; + } - Exception err = null; - GridNearAtomicUpdateRequestInterface singleReq0 = null; - Map mappings0 = null; + Exception err = null; + GridNearAtomicUpdateRequestInterface singleReq0 = null; + Map mappings0 = null; - int size = keys.size(); + int size = keys.size(); - GridCacheVersion futVer = cctx.versions().next(topVer); + GridCacheVersion futVer = cctx.versions().next(topVer); - GridCacheVersion updVer; + GridCacheVersion updVer; - // Assign version on near node in CLOCK ordering mode even if fastMap is false. - if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { - updVer = this.updVer; + // Assign version on near node in CLOCK ordering mode even if fastMap is false. + if (cctx.config().getAtomicWriteOrderMode() == CLOCK) { + updVer = this.updVer; - if (updVer == null) { - updVer = cctx.versions().next(topVer); + if (updVer == null) { + updVer = cctx.versions().next(topVer); - if (log.isDebugEnabled()) - log.debug("Assigned fast-map version for update on near node: " + updVer); + if (log.isDebugEnabled()) + log.debug("Assigned fast-map version for update on near node: " + updVer); + } } - } - else - updVer = null; - - try { - if (size == 1 && !fastMap) { - assert remapKeys == null || remapKeys.size() == 1; + else + updVer = null; - singleReq0 = mapSingleUpdate(topVer, topNodes, futVer, updVer); - } - else { - Map pendingMappings = mapUpdate(topNodes, - topVer, - futVer, - updVer, - remapKeys); + try { + if (size == 1 && !fastMap) { + assert remapKeys == null || remapKeys.size() == 1; - if (pendingMappings.size() == 1) - singleReq0 = F.firstValue(pendingMappings); + singleReq0 = mapSingleUpdate(topVer, topNodes, futVer, updVer); + } else { - if (syncMode == PRIMARY_SYNC) { - mappings0 = U.newHashMap(pendingMappings.size()); + Map pendingMappings = mapUpdate(topNodes, + topVer, + futVer, + updVer, + remapKeys); - for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { - if (req.hasPrimary()) - mappings0.put(req.nodeId(), req); + if (pendingMappings.size() == 1) + singleReq0 = F.firstValue(pendingMappings); + else { + if (syncMode == PRIMARY_SYNC) { + mappings0 = U.newHashMap(pendingMappings.size()); + + for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { + if (req.hasPrimary()) + mappings0.put(req.nodeId(), req); + } } - } - else - mappings0 = pendingMappings; + else + mappings0 = pendingMappings; - assert !mappings0.isEmpty() || size == 0 : this; + assert !mappings0.isEmpty() || size == 0 : GridNearAtomicUpdateFuture.this; + } } - } - synchronized (this) { - assert this.futVer == null : this; - assert this.topVer == AffinityTopologyVersion.ZERO : this; + synchronized (this) { + assert this.futVer == null : this; + assert this.topVer == AffinityTopologyVersion.ZERO : this; - this.topVer = topVer; - this.updVer = updVer; - this.futVer = futVer; + this.topVer = topVer; + this.updVer = updVer; + this.futVer = futVer; - resCnt = 0; + resCnt = 0; - singleReq = singleReq0; - mappings = mappings0; + singleReq = singleReq0; + mappings = mappings0; - this.remapKeys = null; + this.remapKeys = null; + } + } + catch (Exception e) { + err = e; } - } - catch (Exception e) { - err = e; - } - if (err != null) { - onDone(err); + if (err != null) { + onDone(err); - return; - } + return; + } - if (storeFuture()) { - if (!cctx.mvcc().addAtomicFuture(futVer, this)) { - assert isDone() : this; + if (storeFuture()) { + if (!cctx.mvcc().addAtomicFuture(futVer, GridNearAtomicUpdateFuture.this)) { + assert isDone() : GridNearAtomicUpdateFuture.this; - return; + return; + } } - } - // Optimize mapping for single key. - if (singleReq0 != null) - mapSingle(singleReq0.nodeId(), singleReq0); - else { - assert mappings0 != null; + // Optimize mapping for single key. + if (singleReq0 != null) + mapSingle(singleReq0.nodeId(), singleReq0); + else { + assert mappings0 != null; - if (size == 0) - onDone(new GridCacheReturn(cctx, true, true, null, true)); - else - doUpdate(mappings0); + if (size == 0) + onDone(new GridCacheReturn(cctx, true, true, null, true)); + else + doUpdate(mappings0); + } } - } - /** - * @param topVer Topology version. - * @return Future. - */ - @Nullable private synchronized GridFutureAdapter completeFuture0(AffinityTopologyVersion topVer) { - if (this.topVer == AffinityTopologyVersion.ZERO) - return null; + /** + * @param topVer Topology version. + * @return Future. + */ + @Nullable synchronized GridFutureAdapter completeFuture(AffinityTopologyVersion topVer) { + if (this.topVer == AffinityTopologyVersion.ZERO) + return null; - if (this.topVer.compareTo(topVer) < 0) { - if (topCompleteFut == null) - topCompleteFut = new GridFutureAdapter<>(); + if (this.topVer.compareTo(topVer) < 0) { + if (topCompleteFut == null) + topCompleteFut = new GridFutureAdapter<>(); - return topCompleteFut; + return topCompleteFut; + } + + return null; } - return null; - } + /** + * @return Future version. + */ + GridCacheVersion onFutureDone() { + GridCacheVersion ver0; - /** - * @return Future version. - */ - private GridCacheVersion onFutureDone() { - GridCacheVersion ver0; + GridFutureAdapter fut0; + + synchronized (this) { + fut0 = topCompleteFut; - GridFutureAdapter fut0; + topCompleteFut = null; - synchronized (this) { - fut0 = topCompleteFut; + ver0 = futVer; - topCompleteFut = null; + futVer = null; + } - ver0 = futVer; + if (fut0 != null) + fut0.onDone(); - futVer = null; + return ver0; } - if (fut0 != null) - fut0.onDone(); + /** + * @param topNodes Cache nodes. + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @param remapKeys Keys to remap. + * @return Mapping. + * @throws Exception If failed. + */ + @SuppressWarnings("ConstantConditions") + private Map mapUpdate(Collection topNodes, + AffinityTopologyVersion topVer, + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer, + @Nullable Collection remapKeys) throws Exception { + Iterator it = null; + + if (vals != null) + it = vals.iterator(); + + Iterator conflictPutValsIt = null; + + if (conflictPutVals != null) + conflictPutValsIt = conflictPutVals.iterator(); + + Iterator conflictRmvValsIt = null; + + if (conflictRmvVals != null) + conflictRmvValsIt = conflictRmvVals.iterator(); + + Map pendingMappings = U.newHashMap(topNodes.size()); + + // Create mappings first, then send messages. + for (Object key : keys) { + if (key == null) + throw new NullPointerException("Null key."); + + Object val; + GridCacheVersion conflictVer; + long conflictTtl; + long conflictExpireTime; + + if (vals != null) { + val = it.next(); + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + + if (val == null) + throw new NullPointerException("Null value."); + } + else if (conflictPutVals != null) { + GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); - return ver0; - } + val = conflictPutVal.valueEx(); + conflictVer = conflictPutVal.version(); + conflictTtl = conflictPutVal.ttl(); + conflictExpireTime = conflictPutVal.expireTime(); + } + else if (conflictRmvVals != null) { + val = null; + conflictVer = conflictRmvValsIt.next(); + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } + else { + val = null; + conflictVer = null; + conflictTtl = CU.TTL_NOT_CHANGED; + conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + } - /** - * @param topNodes Cache nodes. - * @param topVer Topology version. - * @param futVer Future version. - * @param updVer Update version. - * @param remapKeys Keys to remap. - * @return Mapping. - * @throws Exception If failed. - */ - @SuppressWarnings("ConstantConditions") - private Map mapUpdate(Collection topNodes, - AffinityTopologyVersion topVer, - GridCacheVersion futVer, - @Nullable GridCacheVersion updVer, - @Nullable Collection remapKeys) throws Exception { - Iterator it = null; + if (val == null && op != GridCacheOperation.DELETE) + continue; - if (vals != null) - it = vals.iterator(); + KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); - Iterator conflictPutValsIt = null; + if (remapKeys != null && !remapKeys.contains(cacheKey)) + continue; - if (conflictPutVals != null) - conflictPutValsIt = conflictPutVals.iterator(); + if (op != TRANSFORM) + val = cctx.toCacheObject(val); - Iterator conflictRmvValsIt = null; + Collection affNodes = mapKey(cacheKey, topVer, fastMap); - if (conflictRmvVals != null) - conflictRmvValsIt = conflictRmvVals.iterator(); + if (affNodes.isEmpty()) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); - Map pendingMappings = U.newHashMap(topNodes.size()); + int i = 0; + + for (ClusterNode affNode : affNodes) { + if (affNode == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + + "(all partition nodes left the grid)."); + + UUID nodeId = affNode.id(); + + GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); + + if (mapped == null) { + mapped = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + keys.size()); + + pendingMappings.put(nodeId, mapped); + } - // Create mappings first, then send messages. - for (Object key : keys) { - if (key == null) - throw new NullPointerException("Null key."); + mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); + + i++; + } + } + + return pendingMappings; + } + + /** + * @param topVer Topology version. + * @param futVer Future version. + * @param updVer Update version. + * @return Request. + * @throws Exception If failed. + */ + private GridNearAtomicUpdateRequestInterface mapSingleUpdate(AffinityTopologyVersion topVer, + Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) + throws Exception { + Object key = F.first(keys); Object val; GridCacheVersion conflictVer; @@ -839,273 +1139,169 @@ private Map mapUpdate(Collection long conflictExpireTime; if (vals != null) { - val = it.next(); + // Regular PUT. + val = F.first(vals); conflictVer = null; conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - - if (val == null) - throw new NullPointerException("Null value."); } else if (conflictPutVals != null) { - GridCacheDrInfo conflictPutVal = conflictPutValsIt.next(); + // Conflict PUT. + GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); val = conflictPutVal.valueEx(); conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); + conflictTtl = conflictPutVal.ttl(); conflictExpireTime = conflictPutVal.expireTime(); } else if (conflictRmvVals != null) { + // Conflict REMOVE. val = null; - conflictVer = conflictRmvValsIt.next(); + conflictVer = F.first(conflictRmvVals); conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; } else { + // Regular REMOVE. val = null; conflictVer = null; conflictTtl = CU.TTL_NOT_CHANGED; conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; } + // We still can get here if user pass map with single element. + if (key == null) + throw new NullPointerException("Null key."); + if (val == null && op != GridCacheOperation.DELETE) - continue; + throw new NullPointerException("Null value."); KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); - if (remapKeys != null && !remapKeys.contains(cacheKey)) - continue; - if (op != TRANSFORM) val = cctx.toCacheObject(val); - Collection affNodes = mapKey(cacheKey, topVer, fastMap); + ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); - if (affNodes.isEmpty()) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); + if (primary == null) + throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + + "left the grid)."); - int i = 0; + // Decide whether we will use optimzied version of update request. + boolean optimize = true; - for (ClusterNode affNode : affNodes) { - if (affNode == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + - "(all partition nodes left the grid)."); + for (ClusterNode topNode : topNodes) { + if (topNode.version().compareTo(SINGLE_PUT_MSG_SINCE) < 0) { + optimize = false; - UUID nodeId = affNode.id(); - - GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); - - if (mapped == null) { - mapped = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - keys.size()); - - pendingMappings.put(nodeId, mapped); + break; } + } - mapped.addUpdateEntry(cacheKey, val, conflictTtl, conflictExpireTime, conflictVer, i == 0); - - i++; + if (optimize) { + return new GridNearAtomicSingleUpdateRequest( + cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled()); + } + else { + GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; } } - return pendingMappings; - } - - /** - * @param topVer Topology version. - * @param topNodes Topology nodes. - * @param futVer Future version. - * @param updVer Update version. - * @return Request. - * @throws Exception If failed. - */ - private GridNearAtomicUpdateRequestInterface mapSingleUpdate(AffinityTopologyVersion topVer, - Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) throws Exception { - Object key = F.first(keys); - - Object val; - GridCacheVersion conflictVer; - long conflictTtl; - long conflictExpireTime; - - if (vals != null) { - // Regular PUT. - val = F.first(vals); - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else if (conflictPutVals != null) { - // Conflict PUT. - GridCacheDrInfo conflictPutVal = F.first(conflictPutVals); - - val = conflictPutVal.valueEx(); - conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); - conflictExpireTime = conflictPutVal.expireTime(); - } - else if (conflictRmvVals != null) { - // Conflict REMOVE. - val = null; - conflictVer = F.first(conflictRmvVals); - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - } - else { - // Regular REMOVE. - val = null; - conflictVer = null; - conflictTtl = CU.TTL_NOT_CHANGED; - conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + /** + * @param ret Result from single node. + */ + @SuppressWarnings("unchecked") + private void addInvokeResults(GridCacheReturn ret) { + assert op == TRANSFORM : op; + assert ret.value() == null || ret.value() instanceof Map : ret.value(); + + if (ret.value() != null) { + if (opRes != null) + opRes.mergeEntryProcessResults(ret); + else + opRes = ret; + } } - // We still can get here if user pass map with single element. - if (key == null) - throw new NullPointerException("Null key."); + /** + * @param failedKeys Failed keys. + * @param topVer Topology version for failed update. + * @param err Error cause. + */ + private void addFailedKeys(Collection failedKeys, + AffinityTopologyVersion topVer, + Throwable err) { + CachePartialUpdateCheckedException err0 = this.err; - if (val == null && op != GridCacheOperation.DELETE) - throw new NullPointerException("Null value."); + if (err0 == null) + err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - KeyCacheObject cacheKey = cctx.toCacheKeyObject(key); + Collection keys = new ArrayList<>(failedKeys.size()); - if (op != TRANSFORM) - val = cctx.toCacheObject(val); + for (KeyCacheObject key : failedKeys) + keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); - ClusterNode primary = cctx.affinity().primary(cacheKey, topVer); - - if (primary == null) - throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + - "left the grid)."); - - // Decide whether we will use optimzied version of update request. - boolean optimize = true; - - for (ClusterNode topNode : topNodes) { - if (topNode.version().compareTo(SINGLE_PUT_MSG_SINCE) < 0) { - optimize = false; - - break; - } + err0.add(keys, err, topVer); } - if (optimize) { - return new GridNearAtomicSingleUpdateRequest( - cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled()); - } - else { - GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - true); - - return req; - } - } - - /** - * @param ret Result from single node. - */ - @SuppressWarnings("unchecked") - private void addInvokeResults(GridCacheReturn ret) { - assert op == TRANSFORM : op; - assert ret.value() == null || ret.value() instanceof Map : ret.value(); - - if (ret.value() != null) { - if (opRes != null) - opRes.mergeEntryProcessResults(ret); - else - opRes = ret; + /** {@inheritDoc} */ + @Override public synchronized String toString() { + return S.toString(UpdateState.class, this); } } - /** - * @param failedKeys Failed keys. - * @param topVer Topology version for failed update. - * @param err Error cause. - */ - private void addFailedKeys(Collection failedKeys, - AffinityTopologyVersion topVer, - Throwable err) { - CachePartialUpdateCheckedException err0 = this.err; - - if (err0 == null) - err0 = this.err = new CachePartialUpdateCheckedException("Failed to update keys (retry update if possible)."); - - Collection keys = new ArrayList<>(failedKeys.size()); - - for (KeyCacheObject key : failedKeys) - keys.add(cctx.cacheObjectContext().unwrapBinaryIfNeeded(key, keepBinary, false)); - - err0.add(keys, err, topVer); - } - /** {@inheritDoc} */ public String toString() { return S.toString(GridNearAtomicUpdateFuture.class, this, super.toString()); From 3967130f54fa21d25e7e284ecabaf004b937b921 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Wed, 3 Feb 2016 15:53:07 +0300 Subject: [PATCH 08/34] IGNITE-2523: Finalization. --- .../GridNearAtomicSingleUpdateRequest.java | 188 ++++++------------ .../atomic/GridNearAtomicUpdateRequest.java | 186 ++++++----------- .../GridNearAtomicUpdateRequestInterface.java | 144 +++++++++++--- 3 files changed, 238 insertions(+), 280 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 9ef0b6c612289..fea67c0220c5e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -270,229 +270,164 @@ else if (val != null) { return CACHE_MSG_IDX; } - /** - * @return Mapped node ID. - */ - public UUID nodeId() { + /** {@inheritDoc} */ + @Override public UUID nodeId() { return nodeId; } - /** - * @param nodeId Node ID. - */ - public void nodeId(UUID nodeId) { + /** {@inheritDoc} */ + @Override public void nodeId(UUID nodeId) { this.nodeId = nodeId; } - /** - * @return Subject ID. - */ - public UUID subjectId() { + /** {@inheritDoc} */ + @Override public UUID subjectId() { return subjId; } - /** - * @return Task name hash. - */ - public int taskNameHash() { + /** {@inheritDoc} */ + @Override public int taskNameHash() { return taskNameHash; } - /** - * @return Future version. - */ - public GridCacheVersion futureVersion() { + /** {@inheritDoc} */ + @Override public GridCacheVersion futureVersion() { return futVer; } - /** - * @return Flag indicating whether this is fast-map udpate. - */ - public boolean fastMap() { + /** {@inheritDoc} */ + @Override public boolean fastMap() { return fastMap; } - /** - * @return Update version for fast-map request. - */ - public GridCacheVersion updateVersion() { + /** {@inheritDoc} */ + @Override public GridCacheVersion updateVersion() { return updateVer; } - /** - * @return Topology version. - */ + /** {@inheritDoc} */ @Override public AffinityTopologyVersion topologyVersion() { return topVer; } - /** - * @return Topology locked flag. - */ - public boolean topologyLocked() { + /** {@inheritDoc} */ + @Override public boolean topologyLocked() { return topLocked; } - /** - * @return {@code True} if request sent from client node. - */ - public boolean clientRequest() { + /** {@inheritDoc} */ + @Override public boolean clientRequest() { return clientReq; } - /** - * @return Cache write synchronization mode. - */ - public CacheWriteSynchronizationMode writeSynchronizationMode() { + /** {@inheritDoc} */ + @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { return syncMode; } - /** - * @return Expiry policy. - */ - public ExpiryPolicy expiry() { + /** {@inheritDoc} */ + @Override public ExpiryPolicy expiry() { return expiryPlc; } - /** - * @return Return value flag. - */ - public boolean returnValue() { + /** {@inheritDoc} */ + @Override public boolean returnValue() { return retval; } - /** - * @return Filter. - */ - @Nullable public CacheEntryPredicate[] filter() { + /** {@inheritDoc} */ + @Override @Nullable public CacheEntryPredicate[] filter() { return filter; } - /** - * @return Skip write-through to a persistent storage. - */ - public boolean skipStore() { + /** {@inheritDoc} */ + @Override public boolean skipStore() { return skipStore; } - /** - * @return Keep binary flag. - */ - public boolean keepBinary() { + /** {@inheritDoc} */ + @Override public boolean keepBinary() { return keepBinary; } - /** - * @return Keys for this update request. - */ - public List keys() { + /** {@inheritDoc} */ + @Override public List keys() { return Collections.singletonList(key); } - /** - * @return Values for this update request. - */ - public List values() { + /** {@inheritDoc} */ + @Override public List values() { return Collections.singletonList(op == TRANSFORM ? entryProc : val); } - /** - * @return Update operation. - */ - public GridCacheOperation operation() { + /** {@inheritDoc} */ + @Override public GridCacheOperation operation() { return op; } - /** - * @return Optional arguments for entry processor. - */ - @Nullable public Object[] invokeArguments() { + /** {@inheritDoc} */ + @Override @Nullable public Object[] invokeArguments() { return invokeArgs; } - /** - * @param idx Key index. - * @return Value. - */ + /** {@inheritDoc} */ @SuppressWarnings("unchecked") - public CacheObject value(int idx) { + @Override public CacheObject value(int idx) { assert idx == 0; assert op == UPDATE : op; return val; } - /** - * @param idx Key index. - * @return Entry processor. - */ + /** {@inheritDoc} */ @SuppressWarnings("unchecked") - public EntryProcessor entryProcessor(int idx) { + @Override public EntryProcessor entryProcessor(int idx) { assert idx == 0; assert op == TRANSFORM : op; return entryProc; } - /** - * @param idx Index to get. - * @return Write value - either value, or transform closure. - */ - public CacheObject writeValue(int idx) { + /** {@inheritDoc} */ + @Override public CacheObject writeValue(int idx) { assert idx == 0; return val; } - /** - * @return Conflict versions. - */ - @Nullable public List conflictVersions() { + /** {@inheritDoc} */ + @Override @Nullable public List conflictVersions() { return conflictVer == null ? null : Collections.singletonList(conflictVer); } - /** - * @param idx Index. - * @return Conflict version. - */ - @Nullable public GridCacheVersion conflictVersion(int idx) { + /** {@inheritDoc} */ + @Override @Nullable public GridCacheVersion conflictVersion(int idx) { assert idx == 0; return conflictVer; } - /** - * @param idx Index. - * @return Conflict TTL. - */ - public long conflictTtl(int idx) { + /** {@inheritDoc} */ + @Override public long conflictTtl(int idx) { assert idx == 0; return conflictTtl; } - /** - * @param idx Index. - * @return Conflict expire time. - */ - public long conflictExpireTime(int idx) { + /** {@inheritDoc} */ + @Override public long conflictExpireTime(int idx) { assert idx == 0; return conflictExpireTime; } - /** - * @return Flag indicating whether this request contains primary keys. - */ - public boolean hasPrimary() { + /** {@inheritDoc} */ + @Override public boolean hasPrimary() { return true; } - /** - * @param res Response. - * @return {@code True} if current response was {@code null}. - */ - public boolean onResponse(GridNearAtomicUpdateResponse res) { + /** {@inheritDoc} */ + @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { if (this.res == null) { this.res = res; @@ -502,15 +437,12 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { return false; } - /** - * @return Response. - */ - @Nullable public GridNearAtomicUpdateResponse response() { + /** {@inheritDoc} */ + @Override @Nullable public GridNearAtomicUpdateResponse response() { return res; } - /** {@inheritDoc} - * @param ctx*/ + /** {@inheritDoc} */ @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { super.prepareMarshal(ctx); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 674a5befc879b..a86622fc0cc40 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -253,115 +253,83 @@ public GridNearAtomicUpdateRequest( return CACHE_MSG_IDX; } - /** - * @return Mapped node ID. - */ - public UUID nodeId() { + /** {@inheritDoc} */ + @Override public UUID nodeId() { return nodeId; } - /** - * @param nodeId Node ID. - */ - public void nodeId(UUID nodeId) { + /** {@inheritDoc} */ + @Override public void nodeId(UUID nodeId) { this.nodeId = nodeId; } - /** - * @return Subject ID. - */ - public UUID subjectId() { + /** {@inheritDoc} */ + @Override public UUID subjectId() { return subjId; } - /** - * @return Task name hash. - */ - public int taskNameHash() { + /** {@inheritDoc} */ + @Override public int taskNameHash() { return taskNameHash; } - /** - * @return Future version. - */ - public GridCacheVersion futureVersion() { + /** {@inheritDoc} */ + @Override public GridCacheVersion futureVersion() { return futVer; } - /** - * @return Flag indicating whether this is fast-map udpate. - */ - public boolean fastMap() { + /** {@inheritDoc} */ + @Override public boolean fastMap() { return fastMap; } - /** - * @return Update version for fast-map request. - */ - public GridCacheVersion updateVersion() { + /** {@inheritDoc} */ + @Override public GridCacheVersion updateVersion() { return updateVer; } - /** - * @return Topology version. - */ + /** {@inheritDoc} */ @Override public AffinityTopologyVersion topologyVersion() { return topVer; } - /** - * @return Topology locked flag. - */ - public boolean topologyLocked() { + /** {@inheritDoc} */ + @Override public boolean topologyLocked() { return topLocked; } - /** - * @return {@code True} if request sent from client node. - */ - public boolean clientRequest() { + /** {@inheritDoc} */ + @Override public boolean clientRequest() { return clientReq; } - /** - * @return Cache write synchronization mode. - */ - public CacheWriteSynchronizationMode writeSynchronizationMode() { + /** {@inheritDoc} */ + @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { return syncMode; } - /** - * @return Expiry policy. - */ - public ExpiryPolicy expiry() { + /** {@inheritDoc} */ + @Override public ExpiryPolicy expiry() { return expiryPlc; } - /** - * @return Return value flag. - */ - public boolean returnValue() { + /** {@inheritDoc} */ + @Override public boolean returnValue() { return retval; } - /** - * @return Filter. - */ + /** {@inheritDoc} */ @Nullable public CacheEntryPredicate[] filter() { return filter; } - /** - * @return Skip write-through to a persistent storage. - */ - public boolean skipStore() { + /** {@inheritDoc} */ + @Override public boolean skipStore() { return skipStore; } - /** - * @return Keep binary flag. - */ - public boolean keepBinary() { + /** {@inheritDoc} */ + @Override public boolean keepBinary() { return keepBinary; } @@ -446,79 +414,57 @@ else if (conflictVers != null) } } - /** - * @return Keys for this update request. - */ - public List keys() { + /** {@inheritDoc} */ + @Override public List keys() { return keys; } - /** - * @return Values for this update request. - */ - public List values() { + /** {@inheritDoc} */ + @Override public List values() { return op == TRANSFORM ? entryProcessors : vals; } - /** - * @return Update operation. - */ - public GridCacheOperation operation() { + /** {@inheritDoc} */ + @Override public GridCacheOperation operation() { return op; } - /** - * @return Optional arguments for entry processor. - */ - @Nullable public Object[] invokeArguments() { + /** {@inheritDoc} */ + @Override @Nullable public Object[] invokeArguments() { return invokeArgs; } - /** - * @param idx Key index. - * @return Value. - */ + /** {@inheritDoc} */ @SuppressWarnings("unchecked") - public CacheObject value(int idx) { + @Override public CacheObject value(int idx) { assert op == UPDATE : op; return vals.get(idx); } - /** - * @param idx Key index. - * @return Entry processor. - */ + /** {@inheritDoc} */ @SuppressWarnings("unchecked") - public EntryProcessor entryProcessor(int idx) { + @Override public EntryProcessor entryProcessor(int idx) { assert op == TRANSFORM : op; return entryProcessors.get(idx); } - /** - * @param idx Index to get. - * @return Write value - either value, or transform closure. - */ - public CacheObject writeValue(int idx) { + /** {@inheritDoc} */ + @Override public CacheObject writeValue(int idx) { if (vals != null) return vals.get(idx); return null; } - /** - * @return Conflict versions. - */ - @Nullable public List conflictVersions() { + /** {@inheritDoc} */ + @Override @Nullable public List conflictVersions() { return conflictVers; } - /** - * @param idx Index. - * @return Conflict version. - */ - @Nullable public GridCacheVersion conflictVersion(int idx) { + /** {@inheritDoc} */ + @Override @Nullable public GridCacheVersion conflictVersion(int idx) { if (conflictVers != null) { assert idx >= 0 && idx < conflictVers.size(); @@ -528,11 +474,8 @@ public CacheObject writeValue(int idx) { return null; } - /** - * @param idx Index. - * @return Conflict TTL. - */ - public long conflictTtl(int idx) { + /** {@inheritDoc} */ + @Override public long conflictTtl(int idx) { if (conflictTtls != null) { assert idx >= 0 && idx < conflictTtls.size(); @@ -542,11 +485,8 @@ public long conflictTtl(int idx) { return CU.TTL_NOT_CHANGED; } - /** - * @param idx Index. - * @return Conflict expire time. - */ - public long conflictExpireTime(int idx) { + /** {@inheritDoc} */ + @Override public long conflictExpireTime(int idx) { if (conflictExpireTimes != null) { assert idx >= 0 && idx < conflictExpireTimes.size(); @@ -556,18 +496,13 @@ public long conflictExpireTime(int idx) { return CU.EXPIRE_TIME_CALCULATE; } - /** - * @return Flag indicating whether this request contains primary keys. - */ - public boolean hasPrimary() { + /** {@inheritDoc} */ + @Override public boolean hasPrimary() { return hasPrimary; } - /** - * @param res Response. - * @return {@code True} if current response was {@code null}. - */ - public boolean onResponse(GridNearAtomicUpdateResponse res) { + /** {@inheritDoc} */ + @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { if (this.res == null) { this.res = res; @@ -577,15 +512,12 @@ public boolean onResponse(GridNearAtomicUpdateResponse res) { return false; } - /** - * @return Response. - */ - @Nullable public GridNearAtomicUpdateResponse response() { + /** {@inheritDoc} */ + @Override @Nullable public GridNearAtomicUpdateResponse response() { return res; } - /** {@inheritDoc} - * @param ctx*/ + /** {@inheritDoc} */ @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { super.prepareMarshal(ctx); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java index 2ef4bae22db4e..8115f9fdd3cfc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java @@ -35,16 +35,36 @@ * Base interface for near atomic update interfaces. */ public interface GridNearAtomicUpdateRequestInterface { - public List keys(); + /** + * @return Message ID. + */ + public long messageId(); - public AffinityTopologyVersion topologyVersion(); + /** + * @return Mapped node ID. + */ + public UUID nodeId(); - public GridCacheVersion futureVersion(); + /** + * @param nodeId Node ID. + */ + public void nodeId(UUID nodeId); - public boolean returnValue(); + /** + * @return Subject ID. + */ + public UUID subjectId(); + /** + * @return Task name hash. + */ public int taskNameHash(); + /** + * @return Future version. + */ + public GridCacheVersion futureVersion(); + /** * @return Flag indicating whether this is fast-map udpate. */ @@ -55,51 +75,125 @@ public interface GridNearAtomicUpdateRequestInterface { */ public GridCacheVersion updateVersion(); - public boolean clientRequest(); + /** + * @return Topology version. + */ + public AffinityTopologyVersion topologyVersion(); + /** + * @return Topology locked flag. + */ public boolean topologyLocked(); - public ExpiryPolicy expiry(); + /** + * @return {@code True} if request sent from client node. + */ + public boolean clientRequest(); - public boolean skipStore(); + /** + * @return Cache write synchronization mode. + */ + public CacheWriteSynchronizationMode writeSynchronizationMode(); - public GridCacheOperation operation(); + /** + * @return Expiry policy. + */ + public ExpiryPolicy expiry(); - public CacheWriteSynchronizationMode writeSynchronizationMode(); + /** + * @return Return value flag. + */ + public boolean returnValue(); - public UUID subjectId(); + /** + * @return Filter. + */ + @Nullable public CacheEntryPredicate[] filter(); - @Nullable public Object[] invokeArguments(); + /** + * @return Skip write-through to a persistent storage. + */ + public boolean skipStore(); + /** + * @return Keep binary flag. + */ public boolean keepBinary(); - @Nullable public CacheEntryPredicate[] filter(); + /** + * @return Keys for this update request. + */ + public List keys(); - public UUID nodeId(); + /** + * @return Values for this update request. + */ + public List values(); - public void nodeId(UUID nodeId); + /** + * @return Update operation. + */ + public GridCacheOperation operation(); - public boolean hasPrimary(); + /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments(); + + /** + * @param idx Key index. + * @return Value. + */ + public CacheObject value(int idx); + + /** + * @param idx Key index. + * @return Entry processor. + */ + public EntryProcessor entryProcessor(int idx); + + /** + * @param idx Index to get. + * @return Write value - either value, or transform closure. + */ + public CacheObject writeValue(int idx); + /** + * @return Conflict versions. + */ @Nullable public List conflictVersions(); + /** + * @param idx Index. + * @return Conflict version. + */ @Nullable public GridCacheVersion conflictVersion(int idx); + /** + * @param idx Index. + * @return Conflict TTL. + */ public long conflictTtl(int idx); + /** + * @param idx Index. + * @return Conflict expire time. + */ public long conflictExpireTime(int idx); - public List values(); - - public CacheObject value(int idx); - - public long messageId(); - - public EntryProcessor entryProcessor(int idx); + /** + * @return Flag indicating whether this request contains primary keys. + */ + public boolean hasPrimary(); - public CacheObject writeValue(int idx); + /** + * @param res Response. + * @return {@code True} if current response was {@code null}. + */ + public boolean onResponse(GridNearAtomicUpdateResponse res); + /** + * @return Response. + */ @Nullable public GridNearAtomicUpdateResponse response(); - - public boolean onResponse(GridNearAtomicUpdateResponse res); } From d3e1645aaeb8fd9393744cb087a9ddde27f2e95b Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Thu, 4 Feb 2016 10:52:48 +0300 Subject: [PATCH 09/34] IGNITE-2523: Fixed message count tests. --- .../GridCacheAtomicMessageCountSelfTest.java | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java index 0e17102daea78..cda86ba765a72 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java @@ -28,6 +28,7 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; @@ -138,6 +139,7 @@ protected void checkMessages(boolean clientMode, TestCommunicationSpi commSpi = (TestCommunicationSpi)grid(0).configuration().getCommunicationSpi(); commSpi.registerMessage(GridNearAtomicUpdateRequest.class); + commSpi.registerMessage(GridNearAtomicSingleUpdateRequest.class); commSpi.registerMessage(GridDhtAtomicUpdateRequest.class); int putCnt = 15; @@ -166,22 +168,22 @@ protected void checkMessages(boolean clientMode, jcache(0).put(i, i); } - assertEquals(expNearCnt, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); - assertEquals(expDhtCnt, commSpi.messageCount(GridDhtAtomicUpdateRequest.class)); + assertEquals(expNearCnt, nearRequestsCount(commSpi)); + assertEquals(expDhtCnt, dhtRequestsCount(commSpi)); if (writeOrderMode == CLOCK) { for (int i = 1; i < 4; i++) { commSpi = (TestCommunicationSpi)grid(i).configuration().getCommunicationSpi(); - assertEquals(0, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); - assertEquals(0, commSpi.messageCount(GridDhtAtomicUpdateRequest.class)); + assertEquals(0, nearRequestsCount(commSpi)); + assertEquals(0, dhtRequestsCount(commSpi)); } } else { for (int i = 1; i < 4; i++) { commSpi = (TestCommunicationSpi)grid(i).configuration().getCommunicationSpi(); - assertEquals(0, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); + assertEquals(0, nearRequestsCount(commSpi)); } } } @@ -190,6 +192,27 @@ protected void checkMessages(boolean clientMode, } } + /** + * Get amount of near update requests. + * + * @param commSpi Communication SPI. + * @return Count. + */ + private int nearRequestsCount(TestCommunicationSpi commSpi) { + return commSpi.messageCount(GridNearAtomicUpdateRequest.class) + + commSpi.messageCount(GridNearAtomicSingleUpdateRequest.class); + } + + /** + * Get amount of DHT update requests. + * + * @param commSpi Communication SPI. + * @return Count. + */ + private int dhtRequestsCount(TestCommunicationSpi commSpi) { + return commSpi.messageCount(GridDhtAtomicUpdateRequest.class); + } + /** * Test communication SPI. */ @@ -229,12 +252,5 @@ public int messageCount(Class cls) { return cntr == null ? 0 : cntr.get(); } - - /** - * Resets counter to zero. - */ - public void resetCount() { - cntMap.clear(); - } } } \ No newline at end of file From 0128f988c60cdbd9aec6996626b6ffb1ad1fa30e Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Thu, 4 Feb 2016 10:54:25 +0300 Subject: [PATCH 10/34] IGNITE-2523: Fixed IgniteCacheAtomicStopBusySelfTest. --- .../processors/cache/IgniteCacheAtomicStopBusySelfTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java index cdb7907330d9f..024ff2f7e4699 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.cache; import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; /** @@ -32,6 +33,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPut() throws Exception { bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); } @@ -39,6 +41,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPutBatch() throws Exception { bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); } @@ -46,6 +49,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPutAsync() throws Exception { bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); } @@ -53,6 +57,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testRemove() throws Exception { bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); } From 7e09a146acefccc885e78c57ca85f754d4db5d45 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Thu, 4 Feb 2016 10:59:59 +0300 Subject: [PATCH 11/34] IGNITE-2523: Fixed several other tests. --- ...niteCacheClientNodeChangingTopologyTest.java | 17 ++++++++++++++++- ...eAtomicInvalidPartitionHandlingSelfTest.java | 7 +++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index 13f2598c10267..c83af512474db 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -61,7 +61,9 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter; import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestInterface; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; @@ -231,7 +233,10 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, // Block messages requests for both nodes. spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -273,6 +278,7 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, // Block messages requests for single node. spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); putFut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -360,10 +366,16 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio // Block messages requests for both nodes. spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite2.localNode().id()); spi.record(GridNearAtomicUpdateRequest.class); + spi.record(GridNearAtomicSingleUpdateRequest.class); final IgniteCache cache = ignite3.cache(null); @@ -400,7 +412,7 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio assertEquals(3, msgs.size()); for (Object msg : msgs) - assertTrue(((GridNearAtomicUpdateRequest)msg).clientRequest()); + assertTrue(((GridNearAtomicUpdateRequestInterface)msg).clientRequest()); map.put(primaryKey(ignite0.cache(null)), 3); map.put(primaryKey(ignite1.cache(null)), 4); @@ -458,7 +470,10 @@ private void atomicGetAndPut(CacheAtomicWriteOrderMode writeOrder) throws Except // Block messages requests for both nodes. spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java index 74d2d09812e07..c3bd369e5d4b7 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java @@ -477,8 +477,11 @@ private static class DelayCommunicationSpi extends TcpCommunicationSpi { private boolean delayMessage(GridIoMessage msg) { Object origMsg = msg.message(); - return delay && - ((origMsg instanceof GridNearAtomicUpdateRequest) || (origMsg instanceof GridDhtAtomicUpdateRequest)); + return delay && ( + (origMsg instanceof GridNearAtomicUpdateRequest) || + (origMsg instanceof GridNearAtomicSingleUpdateRequest) || + (origMsg instanceof GridDhtAtomicUpdateRequest) + ); } } } \ No newline at end of file From c54873bba2b2a0777a7ade33f5ec3da82c96ce95 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Thu, 4 Feb 2016 11:04:58 +0300 Subject: [PATCH 12/34] IGNITE-2523: Renaming: interface -> base. --- .../dht/atomic/GridDhtAtomicCache.java | 36 +++++++++---------- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 8 ++--- .../GridNearAtomicSingleUpdateRequest.java | 2 +- .../atomic/GridNearAtomicUpdateFuture.java | 20 +++++------ .../atomic/GridNearAtomicUpdateRequest.java | 2 +- ...a => GridNearAtomicUpdateRequestBase.java} | 4 +-- .../distributed/near/GridNearAtomicCache.java | 4 +-- ...teCacheClientNodeChangingTopologyTest.java | 4 +-- 8 files changed, 40 insertions(+), 40 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/{GridNearAtomicUpdateRequestInterface.java => GridNearAtomicUpdateRequestBase.java} (97%) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index cdaa0619b3163..40494c1baec92 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -139,7 +139,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { Integer.getInteger(IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT, 500); /** Update reply closure. */ - private CI2 updateReplyClos; + private CI2 updateReplyClos; /** Pending */ private ConcurrentMap pendingResponses = new ConcurrentHashMap8<>(); @@ -192,9 +192,9 @@ public GridDhtAtomicCache(GridCacheContext ctx, GridCacheConcurrentMap map } }); - updateReplyClos = new CI2() { + updateReplyClos = new CI2() { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - @Override public void apply(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { if (ctx.config().getAtomicWriteOrderMode() == CLOCK) { assert req.writeSynchronizationMode() != FULL_ASYNC : req; @@ -1310,8 +1310,8 @@ else if (!skipVals && ctx.config().isStatisticsEnabled()) */ public void updateAllAsyncInternal( final UUID nodeId, - final GridNearAtomicUpdateRequestInterface req, - final CI2 completionCb + final GridNearAtomicUpdateRequestBase req, + final CI2 completionCb ) { IgniteInternalFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); @@ -1335,8 +1335,8 @@ public void updateAllAsyncInternal( */ public void updateAllAsyncInternal0( UUID nodeId, - GridNearAtomicUpdateRequestInterface req, - CI2 completionCb + GridNearAtomicUpdateRequestBase req, + CI2 completionCb ) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), ctx.deploymentEnabled()); @@ -1558,12 +1558,12 @@ public void updateAllAsyncInternal0( private UpdateBatchResult updateWithBatch( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequestInterface req, + GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -1974,12 +1974,12 @@ private void reloadIfNeeded(final List entries) throws Ignite private UpdateSingleResult updateSingle( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequestInterface req, + GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -2214,8 +2214,8 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable Collection rmvKeys, @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, - final GridNearAtomicUpdateRequestInterface req, + CI2 completionCb, + final GridNearAtomicUpdateRequestBase req, final GridNearAtomicUpdateResponse res, boolean replicate, UpdateBatchResult batchRes, @@ -2593,7 +2593,7 @@ private void unlockEntries(Collection locked, AffinityTopolog * will return false. * @return {@code True} if filter evaluation succeeded. */ - private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestInterface req, + private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { try { return ctx.isAllLocked(entry, req.filter()); @@ -2608,7 +2608,7 @@ private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestI /** * @param req Request to remap. */ - private void remapToNewPrimary(GridNearAtomicUpdateRequestInterface req) { + private void remapToNewPrimary(GridNearAtomicUpdateRequestBase req) { assert req.writeSynchronizationMode() == FULL_ASYNC : req; if (log.isDebugEnabled()) @@ -2687,9 +2687,9 @@ else if (req.operation() == UPDATE) { */ @Nullable private GridDhtAtomicUpdateFuture createDhtFuture( GridCacheVersion writeVer, - GridNearAtomicUpdateRequestInterface updateReq, + GridNearAtomicUpdateRequestBase updateReq, GridNearAtomicUpdateResponse updateRes, - CI2 completionCb, + CI2 completionCb, boolean force ) { if (!force) { @@ -2720,7 +2720,7 @@ else if (req.operation() == UPDATE) { * @param nodeId Sender node ID. * @param req Near atomic update request. */ - private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { + private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequestBase req) { if (log.isDebugEnabled()) log.debug("Processing near atomic update request [nodeId=" + nodeId + ", req=" + req + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index df6b048ba7f20..7820832e54665 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -77,7 +77,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement /** Completion callback. */ @GridToStringExclude - private final CI2 completionCb; + private final CI2 completionCb; /** Mappings. */ @GridToStringInclude @@ -87,7 +87,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement private Map nearReadersEntries; /** Update request. */ - private final GridNearAtomicUpdateRequestInterface updateReq; + private final GridNearAtomicUpdateRequestBase updateReq; /** Update response. */ private final GridNearAtomicUpdateResponse updateRes; @@ -110,9 +110,9 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, - GridNearAtomicUpdateRequestInterface updateReq, + GridNearAtomicUpdateRequestBase updateReq, GridNearAtomicUpdateResponse updateRes ) { this.cctx = cctx; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index fea67c0220c5e..1c304825c5e05 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -57,7 +57,7 @@ * Lite DHT cache update request sent from near node to primary node. */ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequestInterface, GridCacheDeployable { + implements GridNearAtomicUpdateRequestBase, GridCacheDeployable { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 149d277d39624..f89455160738c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -348,7 +348,7 @@ public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { * @param req Update request. * @param res Update response. */ - private void updateNear(GridNearAtomicUpdateRequestInterface req, GridNearAtomicUpdateResponse res) { + private void updateNear(GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { assert nearEnabled; if (res.remapKeys() != null || !req.hasPrimary()) @@ -450,11 +450,11 @@ private Collection mapKey( * @param nodeId Node ID. * @param req Request. */ - private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestInterface req) { + private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestBase req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequestInterface req, + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } @@ -559,7 +559,7 @@ private class UpdateState { private Collection remapKeys; /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequestInterface singleReq; + private GridNearAtomicUpdateRequestBase singleReq; /** Operation result. */ private GridCacheReturn opRes; @@ -578,7 +578,7 @@ void onNodeLeft(UUID nodeId) { GridNearAtomicUpdateResponse res = null; synchronized (this) { - GridNearAtomicUpdateRequestInterface req; + GridNearAtomicUpdateRequestBase req; if (singleReq != null) req = singleReq.nodeId().equals(nodeId) ? singleReq : null; @@ -611,7 +611,7 @@ void onNodeLeft(UUID nodeId) { */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequestInterface req; + GridNearAtomicUpdateRequestBase req; AffinityTopologyVersion remapTopVer = null; @@ -815,7 +815,7 @@ else if (!nodeErr) * @param req Request. * @param e Error. */ - void onSendError(GridNearAtomicUpdateRequestInterface req, IgniteCheckedException e) { + void onSendError(GridNearAtomicUpdateRequestBase req, IgniteCheckedException e) { synchronized (this) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), req.nodeId(), @@ -843,7 +843,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re } Exception err = null; - GridNearAtomicUpdateRequestInterface singleReq0 = null; + GridNearAtomicUpdateRequestBase singleReq0 = null; Map mappings0 = null; int size = keys.size(); @@ -1128,7 +1128,7 @@ else if (conflictRmvVals != null) { * @return Request. * @throws Exception If failed. */ - private GridNearAtomicUpdateRequestInterface mapSingleUpdate(AffinityTopologyVersion topVer, + private GridNearAtomicUpdateRequestBase mapSingleUpdate(AffinityTopologyVersion topVer, Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) throws Exception { Object key = F.first(keys); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index a86622fc0cc40..08b29be5e5189 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -58,7 +58,7 @@ * Lite DHT cache update request sent from near node to primary node. */ public class GridNearAtomicUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequestInterface, GridCacheDeployable { + implements GridNearAtomicUpdateRequestBase, GridCacheDeployable { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java similarity index 97% rename from modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java rename to modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java index 8115f9fdd3cfc..8ddb181faea55 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestInterface.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java @@ -32,9 +32,9 @@ import java.util.UUID; /** - * Base interface for near atomic update interfaces. + * Base interface for near atomic update requests. */ -public interface GridNearAtomicUpdateRequestInterface { +public interface GridNearAtomicUpdateRequestBase { /** * @return Message ID. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 2a91968981c44..22b9504007b8c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -45,7 +45,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestInterface; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestBase; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx; @@ -127,7 +127,7 @@ public void dht(GridDhtAtomicCache dht) { * @param res Update response. */ public void processNearAtomicUpdateResponse( - GridNearAtomicUpdateRequestInterface req, + GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res ) { if (F.size(res.failedKeys()) == req.keys().size()) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index c83af512474db..18ff8dfb9c894 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -63,7 +63,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestInterface; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestBase; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; @@ -412,7 +412,7 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio assertEquals(3, msgs.size()); for (Object msg : msgs) - assertTrue(((GridNearAtomicUpdateRequestInterface)msg).clientRequest()); + assertTrue(((GridNearAtomicUpdateRequestBase)msg).clientRequest()); map.put(primaryKey(ignite0.cache(null)), 3); map.put(primaryKey(ignite1.cache(null)), 4); From e83408060970aba8f3f98ec7be1d96bab4fa888c Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Thu, 4 Feb 2016 12:05:56 +0300 Subject: [PATCH 13/34] IGNITE-2523: Fixing tests. --- ...teCacheClientNodeChangingTopologyTest.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index 18ff8dfb9c894..8182b33212a08 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -108,6 +108,7 @@ /** * */ +@SuppressWarnings({"unchecked", "unused", "NullArgumentToVariableArgMethod", "ConstantConditions", "UnusedAssignment"}) public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstractTest { /** */ protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); @@ -374,8 +375,7 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite2.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite2.localNode().id()); - spi.record(GridNearAtomicUpdateRequest.class); - spi.record(GridNearAtomicSingleUpdateRequest.class); + spi.record(GridNearAtomicUpdateRequest.class, GridNearAtomicSingleUpdateRequest.class); final IgniteCache cache = ignite3.cache(null); @@ -2019,7 +2019,7 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { private Map, Set> blockCls = new HashMap<>(); /** */ - private Class recordCls; + private Class[] recordClss; /** */ private List recordedMsgs = new ArrayList<>(); @@ -2031,7 +2031,7 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { Object msg0 = ((GridIoMessage)msg).message(); synchronized (this) { - if (recordCls != null && msg0.getClass().equals(recordCls)) + if (isRecordMessage(msg0.getClass())) recordedMsgs.add(msg0); Set blockNodes = blockCls.get(msg0.getClass()); @@ -2053,9 +2053,9 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { /** * @param recordCls Message class to record. */ - void record(@Nullable Class recordCls) { + void record(@Nullable Class... recordCls) { synchronized (this) { - this.recordCls = recordCls; + this.recordClss = recordCls; } } @@ -2109,6 +2109,23 @@ void stopBlock() { blockedMsgs.clear(); } } + + /** + * Decide whether to record message or not. + * + * @param msgCls Message class. + * @return {@code True} if message should be recorded. + */ + private boolean isRecordMessage(Class msgCls) { + if (recordClss != null) { + for (Class recordCls : recordClss) { + if (msgCls.equals(recordCls)) + return true; + } + } + + return false; + } } /** From eaeec214588ced814fb0ef0ef78393af90932c95 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Thu, 4 Feb 2016 18:53:26 +0300 Subject: [PATCH 14/34] ignite-2533 : GridNearLockFuture redesign to optimize memory allocation. --- .../distributed/near/GridNearLockFuture.java | 776 +++++++----------- 1 file changed, 291 insertions(+), 485 deletions(-) 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 5d4fc01eee3f8..d5a476ddc6e6b 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 @@ -20,12 +20,18 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterNode; @@ -39,6 +45,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -63,6 +70,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; +import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.transactions.TransactionIsolation; import org.jetbrains.annotations.Nullable; @@ -73,8 +81,9 @@ /** * Cache lock future. */ -public final class GridNearLockFuture extends GridCompoundIdentityFuture +public final class GridNearLockFuture extends GridFutureAdapter implements GridCacheMvccFuture { + /** */ private static final long serialVersionUID = 0L; @@ -154,6 +163,9 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture sent = new HashMap<>(); + /** * @param cctx Registry. * @param keys Keys to lock. @@ -177,7 +189,6 @@ public GridNearLockFuture( CacheEntryPredicate[] filter, boolean skipStore, boolean keepBinary) { - super(CU.boolReducer()); assert keys != null; @@ -423,22 +434,18 @@ public void complete(boolean success) { * @return {@code True} if node was in the list. */ @SuppressWarnings({"ThrowableInstanceNeverThrown"}) - @Override public boolean onNodeLeft(UUID nodeId) { + @Override public synchronized boolean onNodeLeft(UUID nodeId) { boolean found = false; - for (IgniteInternalFuture fut : futures()) { - if (isMini(fut)) { - MiniFuture f = (MiniFuture)fut; - - if (f.node().id().equals(nodeId)) { - if (log.isDebugEnabled()) - log.debug("Found mini-future for left node [nodeId=" + nodeId + ", mini=" + f + ", fut=" + - this + ']'); + for (GridNearLockMapping mapping : sent.values()) { + if (mapping.node().id().equals(nodeId)) { + if (log.isDebugEnabled()) + log.debug("Found mini-future for left node [nodeId=" + nodeId + ", mini=" + mapping + ", fut=" + + this + ']'); - f.onResult(newTopologyException(null, nodeId)); + onDone(newTopologyException(null, nodeId)); - found = true; - } + found = true; } } @@ -460,62 +467,248 @@ void onResult(UUID nodeId, GridNearLockResponse res) { if (log.isDebugEnabled()) log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); - MiniFuture mini = miniFuture(res.miniId()); + IgniteUuid miniId = res.miniId(); - if (mini != null) { - assert mini.node().id().equals(nodeId); + GridNearLockMapping mapping; - if (log.isDebugEnabled()) - log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']'); - - mini.onResult(res); + synchronized (this) { + mapping = sent.remove(miniId); + } - if (log.isDebugEnabled()) - log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini + - ", res=" + res + ']'); + if (mapping == null) { + U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res + + ", fut=" + this + ']'); return; } - U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res + - ", fut=" + this + ']'); + assert mapping.node().id().equals(nodeId); + + if (log.isDebugEnabled()) + log.debug("Found mini future for response [mini=" + mapping + ", res=" + res + ']'); + + onResult(nodeId, res, mapping); + + checkComplete(); + + if (log.isDebugEnabled()) + log.debug("Future after processed lock response [fut=" + this + ", mini=" + mapping + + ", res=" + res + ']'); + } else if (log.isDebugEnabled()) log.debug("Ignoring lock response from node (future is done) [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); } - /** - * Finds pending mini future by the given mini ID. - * - * @param miniId Mini ID to find. - * @return Mini future. - */ - @SuppressWarnings({"ForLoopReplaceableByForEach", "IfMayBeConditional"}) - 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 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; + private void remap() { + undoLocks(false, false); + + mapOnTopology(true); + } + + private void onResult(UUID nodeId, GridNearLockResponse res, GridNearLockMapping mapping) { + if (res.error() != null) { + if (log.isDebugEnabled()) + log.debug("Finishing mini future with an error due to error in response [miniFut=" + this + + ", res=" + res + ']'); + + // Fail. + if (res.error() instanceof GridCacheLockTimeoutException) + onDone(false); + else + onError(res.error()); + + return; + } + + if (res.clientRemapVersion() != null) { + assert cctx.kernalContext().clientNode(); + + IgniteInternalFuture affFut = + cctx.shared().exchange().affinityReadyFuture(res.clientRemapVersion()); + + if (affFut != null && !affFut.isDone()) { + affFut.listen(new CI1>() { + @Override public void apply(IgniteInternalFuture fut) { + try { + fut.get(); + + remap(); + } + catch (IgniteCheckedException e) { + onError(e); + } + finally { + cctx.shared().txContextReset(); + } + } + }); + } + else + remap(); + + return; + } + + int i = 0; + + for (KeyCacheObject k : mapping.mappedKeys()) { + while (true) { + + GridNearCacheEntry entry = cctx.near().entryExx(k, topVer); + + if (res.dhtVersion(i) == null) { + onDone(new IgniteCheckedException("Failed to receive DHT version from remote node " + + "(will fail the lock): " + res)); + + return; } + + IgniteBiTuple oldValTup = + valMap.get(entry.key()); + + boolean hasBytes = entry.hasValue(); + CacheObject oldVal = entry.rawGet(); + CacheObject newVal = res.value(i); + + GridCacheVersion dhtVer = res.dhtVersion(i); + GridCacheVersion mappedVer = res.mappedVersion(i); + + if (newVal == null) { + if (oldValTup != null) { + if (oldValTup.get1().equals(dhtVer)) + newVal = oldValTup.get2(); + + oldVal = oldValTup.get2(); + } + } + + try { + + // Lock is held at this point, so we can set the + // returned value if any. + entry.resetFromPrimary(newVal, lockVer, dhtVer, nodeId, topVer); + + entry.readyNearLock(lockVer, + mappedVer, + res.committedVersions(), + res.rolledbackVersions(), + res.pending()); + + if (mapping.node().isLocal()) { + // On local node don't record twice if DHT cache already recorded. + boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); + + if (inTx() && implicitTx() && tx.onePhaseCommit()) { + boolean pass = res.filterResult(i); + + tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); + } + + if (record) { + if (cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) + cctx.events().addEvent( + entry.partition(), + entry.key(), + tx, + null, + EVT_CACHE_OBJECT_READ, + newVal, + newVal != null, + oldVal, + hasBytes, + CU.subjectId(tx, cctx.shared()), + null, + inTx() ? tx.resolveTaskName() : null, + keepBinary); + + if (cctx.cache().configuration().isStatisticsEnabled()) + cctx.cache().metrics0().onRead(oldVal != null); + } + + if (log.isDebugEnabled()) + log.debug("Processed response for entry [res=" + res + + ", entry=" + entry + ']'); + + break; // Inner while loop. + } + else { + + boolean readRecordable = false; + + boolean hasOldVal = false; + if (retval) { + readRecordable = cctx.events().isRecordable(EVT_CACHE_OBJECT_READ); + + if (readRecordable) + hasOldVal = entry.hasValue(); + } + + if (inTx()) { + tx.hasRemoteLocks(true); + + if (implicitTx() && tx.onePhaseCommit()) { + boolean pass = res.filterResult(i); + + tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); + } + } + + if (retval) { + if (readRecordable) + cctx.events().addEvent( + entry.partition(), + entry.key(), + tx, + null, + EVT_CACHE_OBJECT_READ, + newVal, + newVal != null, + oldVal, + hasOldVal, + CU.subjectId(tx, cctx.shared()), + null, + inTx() ? tx.resolveTaskName() : null, + keepBinary); + + if (cctx.cache().configuration().isStatisticsEnabled()) + cctx.cache().metrics0().onRead(false); + } + + if (log.isDebugEnabled()) + log.debug("Processed response for entry [res=" + res + ", entry=" + entry + ']'); + + break; // Inner while loop. + } + + } + catch (GridCacheEntryRemovedException ignored) { + if (log.isDebugEnabled()) + log.debug("Failed to add candidates because entry was " + + "removed (will renew)."); + + synchronized (this) { + // Replace old entry with new one. + entries.set(i, + (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); + } + } + } + i++; } - return null; - } + // Proceed and add new future (if any) before completing embedded future. + try { + proceedMapping(); + } + catch (IgniteCheckedException ex) { + onError(ex); + onDone(false); + } + } /** * @param t Error. @@ -570,7 +763,7 @@ private boolean filter(GridCacheEntryEx cached) { * @return {@code True} if locks have been acquired. */ private boolean checkLocks() { - if (!isDone() && initialized() && !hasPending()) { + if (!isDone() && !hasPending()) { synchronized (this) { for (int i = 0; i < entries.size(); i++) { while (true) { @@ -613,6 +806,10 @@ private boolean checkLocks() { return false; } + private synchronized boolean hasPending() { + return !sent.isEmpty(); + } + /** {@inheritDoc} */ @Override public boolean cancel() { if (onCancelled()) @@ -680,32 +877,11 @@ private boolean onComplete(boolean success, boolean distribute) { /** {@inheritDoc} */ @Override public String toString() { - Collection futs = F.viewReadOnly(futures(), new C1, String>() { - @Override public String apply(IgniteInternalFuture f) { - if (isMini(f)) { - MiniFuture m = (MiniFuture)f; - - return "[node=" + m.node().id() + ", loc=" + m.node().isLocal() + ", done=" + f.isDone() + "]"; - } - else - return "[loc=true, done=" + f.isDone() + "]"; - } - }); - return S.toString(GridNearLockFuture.class, this, - "innerFuts", futs, "inTx", inTx(), "super", super.toString()); } - /** - * @param f Future. - * @return {@code True} if mini-future. - */ - private boolean isMini(IgniteInternalFuture f) { - return f.getClass().equals(MiniFuture.class); - } - /** * Basically, future mapping consists from two parts. First, we must determine the topology version this future * will map on. Locking is performed within a user transaction, we must continue to map keys on the same @@ -732,12 +908,12 @@ void map() { topVer = tx.topologyVersionSnapshot(); if (topVer != null) { - for (GridDhtTopologyFuture fut : cctx.shared().exchange().exchangeFutures()){ - if (fut.topologyVersion().equals(topVer)){ + for (GridDhtTopologyFuture fut : cctx.shared().exchange().exchangeFutures()) { + if (fut.topologyVersion().equals(topVer)) { Throwable err = fut.validateCache(cctx); if (err != null) { - onDone(err); + onError(err); return; } @@ -752,8 +928,6 @@ void map() { map(keys, false, true); - markInitialized(); - return; } @@ -785,7 +959,7 @@ synchronized void mapOnTopology(final boolean remap) { Throwable err = fut.validateCache(cctx); if (err != null) { - onDone(err); + onError(err); return; } @@ -807,8 +981,6 @@ synchronized void mapOnTopology(final boolean remap) { } map(keys, remap, false); - - markInitialized(); } else { fut.listen(new CI1>() { @@ -819,7 +991,7 @@ synchronized void mapOnTopology(final boolean remap) { mapOnTopology(remap); } catch (IgniteCheckedException e) { - onDone(e); + onError(e); } finally { cctx.shared().txContextReset(); @@ -833,6 +1005,17 @@ synchronized void mapOnTopology(final boolean remap) { } } + private synchronized void checkComplete() { + if (isDone()) + return; + + if (err != null) + onDone(false, err); + + if (!hasPending()) + onDone(true); + } + /** * Maps keys to nodes. Note that we can not simply group keys by nodes and send lock request as * such approach does not preserve order of lock acquisition. Instead, keys are split in continuous @@ -1083,6 +1266,8 @@ private void map(Iterable keys, boolean remap, boolean topLocked cctx.mvcc().recheckPendingLocks(); proceedMapping(); + + checkComplete(); } catch (IgniteCheckedException ex) { onError(ex); @@ -1124,157 +1309,42 @@ private void proceedMapping0() return; final GridNearLockRequest req = map.request(); - final Collection mappedKeys = map.distributedKeys(); final ClusterNode node = map.node(); if (filter != null && filter.length != 0) req.filter(filter, cctx); - if (node.isLocal()) { - req.miniId(IgniteUuid.randomUuid()); + IgniteUuid id = IgniteUuid.randomUuid(); - if (log.isDebugEnabled()) - log.debug("Before locally locking near request: " + req); - - IgniteInternalFuture fut = dht().lockAllAsync(cctx, cctx.localNode(), req, filter); - - // Add new future. - add(new GridEmbeddedFuture<>( - new C2() { - @Override public Boolean apply(GridNearLockResponse res, Exception e) { - if (CU.isLockTimeoutOrCancelled(e) || - (res != null && CU.isLockTimeoutOrCancelled(res.error()))) - return false; - - if (e != null) { - onError(e); - - return false; - } - - if (res == null) { - onError(new IgniteCheckedException("Lock response is null for future: " + this)); - - return false; - } + synchronized (this) { + sent.put(id, map); + } - if (res.error() != null) { - onError(res.error()); + req.miniId(id); - return false; - } + if (node.isLocal()) { + if (log.isDebugEnabled()) { + log.debug("Before locally locking near request: " + req); + } - if (log.isDebugEnabled()) - log.debug("Acquired lock for local DHT mapping [locId=" + cctx.nodeId() + - ", mappedKeys=" + mappedKeys + ", fut=" + GridNearLockFuture.this + ']'); + final IgniteInternalFuture fut = dht().lockAllAsync(cctx, cctx.localNode(), req, filter); + fut.listen(new IgniteInClosure>() { + @Override public void apply(IgniteInternalFuture future) { + if (future.error() != null) + onDone(future.error()); + else { try { - int i = 0; - - for (KeyCacheObject k : mappedKeys) { - while (true) { - GridNearCacheEntry entry = cctx.near().entryExx(k, req.topologyVersion()); - - try { - IgniteBiTuple oldValTup = - valMap.get(entry.key()); - - boolean hasBytes = entry.hasValue(); - CacheObject oldVal = entry.rawGet(); - CacheObject newVal = res.value(i); - - GridCacheVersion dhtVer = res.dhtVersion(i); - GridCacheVersion mappedVer = res.mappedVersion(i); - - // On local node don't record twice if DHT cache already recorded. - boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); - - if (newVal == null) { - if (oldValTup != null) { - if (oldValTup.get1().equals(dhtVer)) - newVal = oldValTup.get2(); - - oldVal = oldValTup.get2(); - } - } - - // Lock is held at this point, so we can set the - // returned value if any. - entry.resetFromPrimary(newVal, lockVer, dhtVer, node.id(), topVer); - - entry.readyNearLock(lockVer, mappedVer, res.committedVersions(), - res.rolledbackVersions(), res.pending()); - - if (inTx() && implicitTx() && tx.onePhaseCommit()) { - boolean pass = res.filterResult(i); - - tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); - } - - if (record) { - if (cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) - cctx.events().addEvent( - entry.partition(), - entry.key(), - tx, - null, - EVT_CACHE_OBJECT_READ, - newVal, - newVal != null, - oldVal, - hasBytes, - CU.subjectId(tx, cctx.shared()), - null, - inTx() ? tx.resolveTaskName() : null, - keepBinary); - - if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(oldVal != null); - } - - if (log.isDebugEnabled()) - log.debug("Processed response for entry [res=" + res + - ", entry=" + entry + ']'); - - break; // Inner while loop. - } - catch (GridCacheEntryRemovedException ignored) { - if (log.isDebugEnabled()) - log.debug("Failed to add candidates because entry was " + - "removed (will renew)."); - - synchronized (GridNearLockFuture.this) { - // Replace old entry with new one. - entries.set(i, - (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); - } - } - } - - i++; // Increment outside of while loop. - } - - // Proceed and add new future (if any) before completing embedded future. - proceedMapping(); + onResult(node.id(), future.get()); } - catch (IgniteCheckedException ex) { - onError(ex); - - return false; + catch (IgniteCheckedException e) { + onError(e); } - - return true; } - }, - fut)); + } + }); } else { - final MiniFuture fut = new MiniFuture(node, mappedKeys); - - req.miniId(fut.futureId()); - - add(fut); // Append new future. - IgniteInternalFuture txSync = null; if (inTx()) @@ -1288,7 +1358,7 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); cctx.io().send(node, req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { - fut.onResult(ex); + onError(ex); } } else { @@ -1301,7 +1371,8 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); cctx.io().send(node, req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { - fut.onResult(ex); + tx.removeMapping(node.id()); + onError(newTopologyException(ex, node.id())); } catch (IgniteCheckedException e) { onError(e); @@ -1394,269 +1465,4 @@ private class LockTimeoutObject extends GridTimeoutObjectAdapter { return S.toString(LockTimeoutObject.class, this); } } - - /** - * Mini-future for get operations. Mini-futures are only waiting on a single - * node as opposed to multiple nodes. - */ - private class MiniFuture extends GridFutureAdapter { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); - - /** Node ID. */ - @GridToStringExclude - private ClusterNode node; - - /** Keys. */ - @GridToStringInclude - private Collection keys; - - /** */ - private boolean rcvRes; - - /** - * @param node Node. - * @param keys Keys. - */ - MiniFuture( - ClusterNode node, - Collection keys - ) { - this.node = node; - this.keys = keys; - } - - /** - * @return Future ID. - */ - IgniteUuid futureId() { - return futId; - } - - /** - * @return Node ID. - */ - public ClusterNode node() { - return node; - } - - /** - * @return Keys. - */ - public Collection keys() { - return keys; - } - - /** - * @param e Node left exception. - */ - void onResult(ClusterTopologyCheckedException e) { - if (isDone()) - return; - - synchronized (this) { - if (!rcvRes) - rcvRes = true; - else - return; - } - - if (log.isDebugEnabled()) - log.debug("Remote node left grid while sending or waiting for reply (will fail): " + this); - - if (tx != null) - tx.removeMapping(node.id()); - - // Primary node left the grid, so fail the future. - GridNearLockFuture.this.onDone(newTopologyException(e, node.id())); - - onDone(true); - } - - /** - * @param res Result callback. - */ - void onResult(GridNearLockResponse res) { - synchronized (this) { - if (!rcvRes) - rcvRes = true; - else - return; - } - - if (res.error() != null) { - if (log.isDebugEnabled()) - log.debug("Finishing mini future with an error due to error in response [miniFut=" + this + - ", res=" + res + ']'); - - // Fail. - if (res.error() instanceof GridCacheLockTimeoutException) - onDone(false); - else - onDone(res.error()); - - return; - } - - if (res.clientRemapVersion() != null) { - assert cctx.kernalContext().clientNode(); - - IgniteInternalFuture affFut = - cctx.shared().exchange().affinityReadyFuture(res.clientRemapVersion()); - - if (affFut != null && !affFut.isDone()) { - affFut.listen(new CI1>() { - @Override public void apply(IgniteInternalFuture fut) { - try { - fut.get(); - - remap(); - } - catch (IgniteCheckedException e) { - onDone(e); - } - finally { - cctx.shared().txContextReset(); - } - } - }); - } - else - remap(); - } - else { - int i = 0; - - AffinityTopologyVersion topVer = GridNearLockFuture.this.topVer; - - for (KeyCacheObject k : keys) { - while (true) { - GridNearCacheEntry entry = cctx.near().entryExx(k, topVer); - - try { - if (res.dhtVersion(i) == null) { - onDone(new IgniteCheckedException("Failed to receive DHT version from remote node " + - "(will fail the lock): " + res)); - - return; - } - - IgniteBiTuple oldValTup = valMap.get(entry.key()); - - CacheObject oldVal = entry.rawGet(); - boolean hasOldVal = false; - CacheObject newVal = res.value(i); - - boolean readRecordable = false; - - if (retval) { - readRecordable = cctx.events().isRecordable(EVT_CACHE_OBJECT_READ); - - if (readRecordable) - hasOldVal = entry.hasValue(); - } - - GridCacheVersion dhtVer = res.dhtVersion(i); - GridCacheVersion mappedVer = res.mappedVersion(i); - - if (newVal == null) { - if (oldValTup != null) { - if (oldValTup.get1().equals(dhtVer)) - newVal = oldValTup.get2(); - - oldVal = oldValTup.get2(); - } - } - - // Lock is held at this point, so we can set the - // returned value if any. - entry.resetFromPrimary(newVal, lockVer, dhtVer, node.id(), topVer); - - if (inTx()) { - tx.hasRemoteLocks(true); - - if (implicitTx() && tx.onePhaseCommit()) { - boolean pass = res.filterResult(i); - - tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); - } - } - - entry.readyNearLock(lockVer, - mappedVer, - res.committedVersions(), - res.rolledbackVersions(), - res.pending()); - - if (retval) { - if (readRecordable) - cctx.events().addEvent( - entry.partition(), - entry.key(), - tx, - null, - EVT_CACHE_OBJECT_READ, - newVal, - newVal != null, - oldVal, - hasOldVal, - CU.subjectId(tx, cctx.shared()), - null, - inTx() ? tx.resolveTaskName() : null, - keepBinary); - - if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(false); - } - - if (log.isDebugEnabled()) - log.debug("Processed response for entry [res=" + res + ", entry=" + entry + ']'); - - break; // Inner while loop. - } - catch (GridCacheEntryRemovedException ignored) { - if (log.isDebugEnabled()) - log.debug("Failed to add candidates because entry was removed (will renew)."); - - synchronized (GridNearLockFuture.this) { - // Replace old entry with new one. - entries.set(i, - (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); - } - } - } - - i++; - } - - try { - proceedMapping(); - } - catch (IgniteCheckedException e) { - onDone(e); - } - - onDone(true); - } - } - - /** - * - */ - private void remap() { - undoLocks(false, false); - - mapOnTopology(true); - - onDone(true); - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(MiniFuture.class, this, "node", node.id(), "super", super.toString()); - } - } } From 1491c1f494e47618191ae7e4f79c67a5fdd9a326 Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Fri, 5 Feb 2016 10:04:04 +0300 Subject: [PATCH 15/34] IGNITE-2523: Renamings. --- .../communication/GridIoMessageFactory.java | 4 +- .../processors/cache/GridCacheIoManager.java | 4 +- .../dht/atomic/GridDhtAtomicCache.java | 40 +- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 8 +- .../GridNearAtomicMultipleUpdateRequest.java | 976 ++++++++++++++++ .../GridNearAtomicSingleUpdateRequest.java | 2 +- .../atomic/GridNearAtomicUpdateFuture.java | 54 +- .../atomic/GridNearAtomicUpdateRequest.java | 1037 +++-------------- .../GridNearAtomicUpdateRequestBase.java | 199 ---- .../distributed/near/GridNearAtomicCache.java | 4 +- .../GridCacheAtomicMessageCountSelfTest.java | 6 +- .../IgniteCacheAtomicStopBusySelfTest.java | 10 +- ...teCacheClientNodeChangingTopologyTest.java | 22 +- ...tomicInvalidPartitionHandlingSelfTest.java | 2 +- 14 files changed, 1184 insertions(+), 1184 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.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 25e07b898907c..88e34c98c0081 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 @@ -69,7 +69,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; 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; @@ -363,7 +363,7 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 40: - msg = new GridNearAtomicUpdateRequest(); + msg = new GridNearAtomicMultipleUpdateRequest(); break; 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 57545af70ea97..8a8f1616b2de6 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,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; 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; @@ -410,7 +410,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 40: { - GridNearAtomicUpdateRequest req = (GridNearAtomicUpdateRequest)msg; + GridNearAtomicMultipleUpdateRequest req = (GridNearAtomicMultipleUpdateRequest)msg; GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse( ctx.cacheId(), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 40494c1baec92..55db70acb1e0c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -139,7 +139,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { Integer.getInteger(IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT, 500); /** Update reply closure. */ - private CI2 updateReplyClos; + private CI2 updateReplyClos; /** Pending */ private ConcurrentMap pendingResponses = new ConcurrentHashMap8<>(); @@ -192,9 +192,9 @@ public GridDhtAtomicCache(GridCacheContext ctx, GridCacheConcurrentMap map } }); - updateReplyClos = new CI2() { + updateReplyClos = new CI2() { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - @Override public void apply(GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { if (ctx.config().getAtomicWriteOrderMode() == CLOCK) { assert req.writeSynchronizationMode() != FULL_ASYNC : req; @@ -250,8 +250,8 @@ else if (res.error() != null) { } }); - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicUpdateRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicMultipleUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicMultipleUpdateRequest req) { processNearAtomicUpdateRequest(nodeId, req); } }); @@ -1310,8 +1310,8 @@ else if (!skipVals && ctx.config().isStatisticsEnabled()) */ public void updateAllAsyncInternal( final UUID nodeId, - final GridNearAtomicUpdateRequestBase req, - final CI2 completionCb + final GridNearAtomicUpdateRequest req, + final CI2 completionCb ) { IgniteInternalFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); @@ -1335,8 +1335,8 @@ public void updateAllAsyncInternal( */ public void updateAllAsyncInternal0( UUID nodeId, - GridNearAtomicUpdateRequestBase req, - CI2 completionCb + GridNearAtomicUpdateRequest req, + CI2 completionCb ) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), ctx.deploymentEnabled()); @@ -1558,12 +1558,12 @@ public void updateAllAsyncInternal0( private UpdateBatchResult updateWithBatch( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequestBase req, + GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -1974,12 +1974,12 @@ private void reloadIfNeeded(final List entries) throws Ignite private UpdateSingleResult updateSingle( ClusterNode node, boolean hasNear, - GridNearAtomicUpdateRequestBase req, + GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -2214,8 +2214,8 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable Collection rmvKeys, @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, - final GridNearAtomicUpdateRequestBase req, + CI2 completionCb, + final GridNearAtomicUpdateRequest req, final GridNearAtomicUpdateResponse res, boolean replicate, UpdateBatchResult batchRes, @@ -2593,7 +2593,7 @@ private void unlockEntries(Collection locked, AffinityTopolog * will return false. * @return {@code True} if filter evaluation succeeded. */ - private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestBase req, + private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { try { return ctx.isAllLocked(entry, req.filter()); @@ -2608,7 +2608,7 @@ private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequestB /** * @param req Request to remap. */ - private void remapToNewPrimary(GridNearAtomicUpdateRequestBase req) { + private void remapToNewPrimary(GridNearAtomicUpdateRequest req) { assert req.writeSynchronizationMode() == FULL_ASYNC : req; if (log.isDebugEnabled()) @@ -2687,9 +2687,9 @@ else if (req.operation() == UPDATE) { */ @Nullable private GridDhtAtomicUpdateFuture createDhtFuture( GridCacheVersion writeVer, - GridNearAtomicUpdateRequestBase updateReq, + GridNearAtomicUpdateRequest updateReq, GridNearAtomicUpdateResponse updateRes, - CI2 completionCb, + CI2 completionCb, boolean force ) { if (!force) { @@ -2720,7 +2720,7 @@ else if (req.operation() == UPDATE) { * @param nodeId Sender node ID. * @param req Near atomic update request. */ - private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequestBase req) { + private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequest req) { if (log.isDebugEnabled()) log.debug("Processing near atomic update request [nodeId=" + nodeId + ", req=" + req + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 7820832e54665..3a31700dcedfc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -77,7 +77,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement /** Completion callback. */ @GridToStringExclude - private final CI2 completionCb; + private final CI2 completionCb; /** Mappings. */ @GridToStringInclude @@ -87,7 +87,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement private Map nearReadersEntries; /** Update request. */ - private final GridNearAtomicUpdateRequestBase updateReq; + private final GridNearAtomicUpdateRequest updateReq; /** Update response. */ private final GridNearAtomicUpdateResponse updateRes; @@ -110,9 +110,9 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, - GridNearAtomicUpdateRequestBase updateReq, + GridNearAtomicUpdateRequest updateReq, GridNearAtomicUpdateResponse updateRes ) { this.cctx = cctx; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java new file mode 100644 index 0000000000000..650d350f76a84 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java @@ -0,0 +1,976 @@ +/* + * 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.atomic; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.processor.EntryProcessor; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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.IgniteExternalizableExpiryPolicy; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; + +/** + * Lite DHT cache update request sent from near node to primary node. + */ +public class GridNearAtomicMultipleUpdateRequest extends GridCacheMessage + implements GridNearAtomicUpdateRequest, GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Target node ID. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Fast map flag. */ + private boolean fastMap; + + /** Update version. Set to non-null if fastMap is {@code true}. */ + private GridCacheVersion updateVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ + private boolean topLocked; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Update operation. */ + private GridCacheOperation op; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** Conflict TTLs. */ + private GridLongList conflictTtls; + + /** Conflict expire times. */ + private GridLongList conflictExpireTimes; + + /** Return value flag. */ + private boolean retval; + + /** Expiry policy. */ + @GridDirectTransient + private ExpiryPolicy expiryPlc; + + /** Expiry policy bytes. */ + private byte[] expiryPlcBytes; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Flag indicating whether request contains primary keys. */ + private boolean hasPrimary; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Skip write-through to a persistent storage. */ + private boolean skipStore; + + /** */ + private boolean clientReq; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** */ + @GridDirectTransient + private GridNearAtomicUpdateResponse res; + + /** Maximum possible size of inner collections. */ + @GridDirectTransient + private int initSize; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridNearAtomicMultipleUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param fastMap Fast map scheme flag. + * @param updateVer Update version set if fast map is performed. + * @param topVer Topology version. + * @param topLocked Topology locked flag. + * @param syncMode Synchronization mode. + * @param op Cache update operation. + * @param retval Return value required flag. + * @param expiryPlc Expiry policy. + * @param invokeArgs Optional arguments for entry processor. + * @param filter Optional filter for atomic check. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param skipStore Skip write-through to a persistent storage. + * @param keepBinary Keep binary flag. + * @param clientReq Client node request flag. + * @param addDepInfo Deployment info flag. + * @param maxEntryCnt Maximum entries count. + */ + public GridNearAtomicMultipleUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + boolean fastMap, + @Nullable GridCacheVersion updateVer, + @NotNull AffinityTopologyVersion topVer, + boolean topLocked, + CacheWriteSynchronizationMode syncMode, + GridCacheOperation op, + boolean retval, + @Nullable ExpiryPolicy expiryPlc, + @Nullable Object[] invokeArgs, + @Nullable CacheEntryPredicate[] filter, + @Nullable UUID subjId, + int taskNameHash, + boolean skipStore, + boolean keepBinary, + boolean clientReq, + boolean addDepInfo, + int maxEntryCnt + ) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.fastMap = fastMap; + this.updateVer = updateVer; + + this.topVer = topVer; + this.topLocked = topLocked; + this.syncMode = syncMode; + this.op = op; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.invokeArgs = invokeArgs; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.clientReq = clientReq; + this.addDepInfo = addDepInfo; + + // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries + // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys + // participate in request. As such, we know upper bound of all collections in request. If this bound is lower + // than 10, we use it. + initSize = Math.min(maxEntryCnt, 10); + + keys = new ArrayList<>(initSize); + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** {@inheritDoc} */ + @Override public UUID nodeId() { + return nodeId; + } + + /** {@inheritDoc} */ + @Override public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } + + /** {@inheritDoc} */ + @Override public UUID subjectId() { + return subjId; + } + + /** {@inheritDoc} */ + @Override public int taskNameHash() { + return taskNameHash; + } + + /** {@inheritDoc} */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** {@inheritDoc} */ + @Override public boolean fastMap() { + return fastMap; + } + + /** {@inheritDoc} */ + @Override public GridCacheVersion updateVersion() { + return updateVer; + } + + /** {@inheritDoc} */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** {@inheritDoc} */ + @Override public boolean topologyLocked() { + return topLocked; + } + + /** {@inheritDoc} */ + @Override public boolean clientRequest() { + return clientReq; + } + + /** {@inheritDoc} */ + @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } + + /** {@inheritDoc} */ + @Override public ExpiryPolicy expiry() { + return expiryPlc; + } + + /** {@inheritDoc} */ + @Override public boolean returnValue() { + return retval; + } + + /** {@inheritDoc} */ + @Nullable public CacheEntryPredicate[] filter() { + return filter; + } + + /** {@inheritDoc} */ + @Override public boolean skipStore() { + return skipStore; + } + + /** {@inheritDoc} */ + @Override public boolean keepBinary() { + return keepBinary; + } + + /** + * @param key Key to add. + * @param val Optional update value. + * @param conflictTtl Conflict TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param primary If given key is primary on this mapping. + */ + @SuppressWarnings("unchecked") + public void addUpdateEntry(KeyCacheObject key, + @Nullable Object val, + long conflictTtl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, + boolean primary) { + EntryProcessor entryProcessor = null; + + if (op == TRANSFORM) { + assert val instanceof EntryProcessor : val; + + entryProcessor = (EntryProcessor)val; + } + + assert val != null || op == DELETE; + + keys.add(key); + + if (entryProcessor != null) { + if (entryProcessors == null) + entryProcessors = new ArrayList<>(initSize); + + entryProcessors.add(entryProcessor); + } + else if (val != null) { + assert val instanceof CacheObject : val; + + if (vals == null) + vals = new ArrayList<>(initSize); + + vals.add((CacheObject)val); + } + + hasPrimary |= primary; + + // In case there is no conflict, do not create the list. + if (conflictVer != null) { + if (conflictVers == null) { + conflictVers = new ArrayList<>(initSize); + + for (int i = 0; i < keys.size() - 1; i++) + conflictVers.add(null); + } + + conflictVers.add(conflictVer); + } + else if (conflictVers != null) + conflictVers.add(null); + + if (conflictTtl >= 0) { + if (conflictTtls == null) { + conflictTtls = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictTtls.add(CU.TTL_NOT_CHANGED); + } + + conflictTtls.add(conflictTtl); + } + + if (conflictExpireTime >= 0) { + if (conflictExpireTimes == null) { + conflictExpireTimes = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + + conflictExpireTimes.add(conflictExpireTime); + } + } + + /** {@inheritDoc} */ + @Override public List keys() { + return keys; + } + + /** {@inheritDoc} */ + @Override public List values() { + return op == TRANSFORM ? entryProcessors : vals; + } + + /** {@inheritDoc} */ + @Override public GridCacheOperation operation() { + return op; + } + + /** {@inheritDoc} */ + @Override @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public CacheObject value(int idx) { + assert op == UPDATE : op; + + return vals.get(idx); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public EntryProcessor entryProcessor(int idx) { + assert op == TRANSFORM : op; + + return entryProcessors.get(idx); + } + + /** {@inheritDoc} */ + @Override public CacheObject writeValue(int idx) { + if (vals != null) + return vals.get(idx); + + return null; + } + + /** {@inheritDoc} */ + @Override @Nullable public List conflictVersions() { + return conflictVers; + } + + /** {@inheritDoc} */ + @Override @Nullable public GridCacheVersion conflictVersion(int idx) { + if (conflictVers != null) { + assert idx >= 0 && idx < conflictVers.size(); + + return conflictVers.get(idx); + } + + return null; + } + + /** {@inheritDoc} */ + @Override public long conflictTtl(int idx) { + if (conflictTtls != null) { + assert idx >= 0 && idx < conflictTtls.size(); + + return conflictTtls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** {@inheritDoc} */ + @Override public long conflictExpireTime(int idx) { + if (conflictExpireTimes != null) { + assert idx >= 0 && idx < conflictExpireTimes.size(); + + return conflictExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** {@inheritDoc} */ + @Override public boolean hasPrimary() { + return hasPrimary; + } + + /** {@inheritDoc} */ + @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { + if (this.res == null) { + this.res = res; + + return true; + } + + return false; + } + + /** {@inheritDoc} */ + @Override @Nullable public GridNearAtomicUpdateResponse response() { + return res; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(keys, cctx); + + if (filter != null) { + boolean hasFilter = false; + + for (CacheEntryPredicate p : filter) { + if (p != null) { + hasFilter = true; + + p.prepareMarshal(cctx); + } + } + + if (!hasFilter) + filter = null; + } + + if (expiryPlc != null && expiryPlcBytes == null) + expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); + + if (op == TRANSFORM) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (entryProcessorsBytes == null) + entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + } + else + prepareMarshalCacheObjects(vals, cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(keys, cctx, ldr); + + if (op == TRANSFORM) { + if (entryProcessors == null) + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + } + else + finishUnmarshalCacheObjects(vals, cctx, ldr); + + if (filter != null) { + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + + if (expiryPlcBytes != null && expiryPlc == null) + expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeBoolean("clientReq", clientReq)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("conflictTtls", conflictTtls)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("fastMap", fastMap)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBoolean("hasPrimary", hasPrimary)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeBoolean("retval", retval)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeBoolean("skipStore", skipStore)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeBoolean("topLocked", topLocked)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("updateVer", updateVer)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + 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: + clientReq = reader.readBoolean("clientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + conflictTtls = reader.readMessage("conflictTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + fastMap = reader.readBoolean("fastMap"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + hasPrimary = reader.readBoolean("hasPrimary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + keys = reader.readCollection("keys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + byte opOrd; + + opOrd = reader.readByte("op"); + + if (!reader.isLastRead()) + return false; + + op = GridCacheOperation.fromOrdinal(opOrd); + + reader.incrementState(); + + case 17: + retval = reader.readBoolean("retval"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + skipStore = reader.readBoolean("skipStore"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 19: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + byte syncModeOrd; + + syncModeOrd = reader.readByte("syncMode"); + + if (!reader.isLastRead()) + return false; + + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + + reader.incrementState(); + + case 21: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + topLocked = reader.readBoolean("topLocked"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + updateVer = reader.readMessage("updateVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearAtomicMultipleUpdateRequest.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 40; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 26; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicMultipleUpdateRequest.class, this, "filter", Arrays.toString(filter), + "parent", super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 1c304825c5e05..1e981afd9a212 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -57,7 +57,7 @@ * Lite DHT cache update request sent from near node to primary node. */ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequestBase, GridCacheDeployable { + implements GridNearAtomicUpdateRequest, GridCacheDeployable { /** */ private static final long serialVersionUID = 0L; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index f89455160738c..879f9f390cb82 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -348,7 +348,7 @@ public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { * @param req Update request. * @param res Update response. */ - private void updateNear(GridNearAtomicUpdateRequestBase req, GridNearAtomicUpdateResponse res) { + private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { assert nearEnabled; if (res.remapKeys() != null || !req.hasPrimary()) @@ -450,11 +450,11 @@ private Collection mapKey( * @param nodeId Node ID. * @param req Request. */ - private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestBase req) { + private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequestBase req, + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } @@ -465,8 +465,8 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestBase req) { if (log.isDebugEnabled()) log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - if (req instanceof GridNearAtomicUpdateRequest) - cctx.io().send(req.nodeId(), (GridNearAtomicUpdateRequest)req, cctx.ioPolicy()); + if (req instanceof GridNearAtomicMultipleUpdateRequest) + cctx.io().send(req.nodeId(), (GridNearAtomicMultipleUpdateRequest)req, cctx.ioPolicy()); else { assert req instanceof GridNearAtomicSingleUpdateRequest; @@ -487,13 +487,13 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequestBase req) { * * @param mappings Mappings to send. */ - private void doUpdate(Map mappings) { + private void doUpdate(Map mappings) { UUID locNodeId = cctx.localNodeId(); - GridNearAtomicUpdateRequest locUpdate = null; + GridNearAtomicMultipleUpdateRequest locUpdate = null; // Send messages to remote nodes first, then run local update. - for (GridNearAtomicUpdateRequest req : mappings.values()) { + for (GridNearAtomicMultipleUpdateRequest req : mappings.values()) { if (locNodeId.equals(req.nodeId())) { assert locUpdate == null : "Cannot have more than one local mapping [locUpdate=" + locUpdate + ", req=" + req + ']'; @@ -515,8 +515,8 @@ private void doUpdate(Map mappings) { if (locUpdate != null) { cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, - new CI2() { - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + new CI2() { + @Override public void apply(GridNearAtomicMultipleUpdateRequest req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -541,7 +541,7 @@ private class UpdateState { /** Mappings if operations is mapped to more than one node. */ @GridToStringInclude - private Map mappings; + private Map mappings; /** */ private int resCnt; @@ -559,7 +559,7 @@ private class UpdateState { private Collection remapKeys; /** Not null is operation is mapped to single node. */ - private GridNearAtomicUpdateRequestBase singleReq; + private GridNearAtomicUpdateRequest singleReq; /** Operation result. */ private GridCacheReturn opRes; @@ -578,7 +578,7 @@ void onNodeLeft(UUID nodeId) { GridNearAtomicUpdateResponse res = null; synchronized (this) { - GridNearAtomicUpdateRequestBase req; + GridNearAtomicUpdateRequest req; if (singleReq != null) req = singleReq.nodeId().equals(nodeId) ? singleReq : null; @@ -611,7 +611,7 @@ void onNodeLeft(UUID nodeId) { */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { - GridNearAtomicUpdateRequestBase req; + GridNearAtomicUpdateRequest req; AffinityTopologyVersion remapTopVer = null; @@ -741,7 +741,7 @@ else if (res.error() != null) { if (rcvAll && nearEnabled) { if (mappings != null) { - for (GridNearAtomicUpdateRequest req0 : mappings.values()) { + for (GridNearAtomicMultipleUpdateRequest req0 : mappings.values()) { GridNearAtomicUpdateResponse res0 = req0.response(); assert res0 != null : req0; @@ -815,7 +815,7 @@ else if (!nodeErr) * @param req Request. * @param e Error. */ - void onSendError(GridNearAtomicUpdateRequestBase req, IgniteCheckedException e) { + void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { synchronized (this) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), req.nodeId(), @@ -843,8 +843,8 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re } Exception err = null; - GridNearAtomicUpdateRequestBase singleReq0 = null; - Map mappings0 = null; + GridNearAtomicUpdateRequest singleReq0 = null; + Map mappings0 = null; int size = keys.size(); @@ -873,7 +873,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re singleReq0 = mapSingleUpdate(topVer, topNodes, futVer, updVer); } else { - Map pendingMappings = mapUpdate(topNodes, + Map pendingMappings = mapUpdate(topNodes, topVer, futVer, updVer, @@ -885,7 +885,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re if (syncMode == PRIMARY_SYNC) { mappings0 = U.newHashMap(pendingMappings.size()); - for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { + for (GridNearAtomicMultipleUpdateRequest req : pendingMappings.values()) { if (req.hasPrimary()) mappings0.put(req.nodeId(), req); } @@ -996,7 +996,7 @@ GridCacheVersion onFutureDone() { * @throws Exception If failed. */ @SuppressWarnings("ConstantConditions") - private Map mapUpdate(Collection topNodes, + private Map mapUpdate(Collection topNodes, AffinityTopologyVersion topVer, GridCacheVersion futVer, @Nullable GridCacheVersion updVer, @@ -1016,7 +1016,7 @@ private Map mapUpdate(Collection if (conflictRmvVals != null) conflictRmvValsIt = conflictRmvVals.iterator(); - Map pendingMappings = U.newHashMap(topNodes.size()); + Map pendingMappings = U.newHashMap(topNodes.size()); // Create mappings first, then send messages. for (Object key : keys) { @@ -1084,10 +1084,10 @@ else if (conflictRmvVals != null) { UUID nodeId = affNode.id(); - GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); + GridNearAtomicMultipleUpdateRequest mapped = pendingMappings.get(nodeId); if (mapped == null) { - mapped = new GridNearAtomicUpdateRequest( + mapped = new GridNearAtomicMultipleUpdateRequest( cctx.cacheId(), nodeId, futVer, @@ -1128,7 +1128,7 @@ else if (conflictRmvVals != null) { * @return Request. * @throws Exception If failed. */ - private GridNearAtomicUpdateRequestBase mapSingleUpdate(AffinityTopologyVersion topVer, + private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) throws Exception { Object key = F.first(keys); @@ -1226,7 +1226,7 @@ else if (conflictRmvVals != null) { cctx.deploymentEnabled()); } else { - GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + GridNearAtomicMultipleUpdateRequest req = new GridNearAtomicMultipleUpdateRequest( cctx.cacheId(), primary.id(), futVer, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 08b29be5e5189..960add7eb0ba3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -17,960 +17,183 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.processor.EntryProcessor; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; -import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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.IgniteExternalizableExpiryPolicy; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.GridLongList; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.processor.EntryProcessor; +import java.util.List; +import java.util.UUID; /** - * Lite DHT cache update request sent from near node to primary node. + * Base interface for near atomic update requests. */ -public class GridNearAtomicUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequestBase, GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Target node ID. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Fast map flag. */ - private boolean fastMap; - - /** Update version. Set to non-null if fastMap is {@code true}. */ - private GridCacheVersion updateVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ - private boolean topLocked; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Update operation. */ - private GridCacheOperation op; - - /** Keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; - - /** Values to update. */ - @GridDirectCollection(CacheObject.class) - private List vals; - - /** Entry processors. */ - @GridDirectTransient - private List> entryProcessors; - - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; - - /** Conflict TTLs. */ - private GridLongList conflictTtls; - - /** Conflict expire times. */ - private GridLongList conflictExpireTimes; - - /** Return value flag. */ - private boolean retval; - - /** Expiry policy. */ - @GridDirectTransient - private ExpiryPolicy expiryPlc; - - /** Expiry policy bytes. */ - private byte[] expiryPlcBytes; - - /** Filter. */ - private CacheEntryPredicate[] filter; - - /** Flag indicating whether request contains primary keys. */ - private boolean hasPrimary; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Skip write-through to a persistent storage. */ - private boolean skipStore; - - /** */ - private boolean clientReq; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** */ - @GridDirectTransient - private GridNearAtomicUpdateResponse res; - - /** Maximum possible size of inner collections. */ - @GridDirectTransient - private int initSize; +public interface GridNearAtomicUpdateRequest { + /** + * @return Message ID. + */ + public long messageId(); /** - * Empty constructor required by {@link Externalizable}. + * @return Mapped node ID. */ - public GridNearAtomicUpdateRequest() { - // No-op. - } + public UUID nodeId(); /** - * Constructor. - * - * @param cacheId Cache ID. * @param nodeId Node ID. - * @param futVer Future version. - * @param fastMap Fast map scheme flag. - * @param updateVer Update version set if fast map is performed. - * @param topVer Topology version. - * @param topLocked Topology locked flag. - * @param syncMode Synchronization mode. - * @param op Cache update operation. - * @param retval Return value required flag. - * @param expiryPlc Expiry policy. - * @param invokeArgs Optional arguments for entry processor. - * @param filter Optional filter for atomic check. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param skipStore Skip write-through to a persistent storage. - * @param keepBinary Keep binary flag. - * @param clientReq Client node request flag. - * @param addDepInfo Deployment info flag. - * @param maxEntryCnt Maximum entries count. */ - public GridNearAtomicUpdateRequest( - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - boolean fastMap, - @Nullable GridCacheVersion updateVer, - @NotNull AffinityTopologyVersion topVer, - boolean topLocked, - CacheWriteSynchronizationMode syncMode, - GridCacheOperation op, - boolean retval, - @Nullable ExpiryPolicy expiryPlc, - @Nullable Object[] invokeArgs, - @Nullable CacheEntryPredicate[] filter, - @Nullable UUID subjId, - int taskNameHash, - boolean skipStore, - boolean keepBinary, - boolean clientReq, - boolean addDepInfo, - int maxEntryCnt - ) { - assert futVer != null; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.fastMap = fastMap; - this.updateVer = updateVer; - - this.topVer = topVer; - this.topLocked = topLocked; - this.syncMode = syncMode; - this.op = op; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.invokeArgs = invokeArgs; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.clientReq = clientReq; - this.addDepInfo = addDepInfo; - - // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries - // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys - // participate in request. As such, we know upper bound of all collections in request. If this bound is lower - // than 10, we use it. - initSize = Math.min(maxEntryCnt, 10); - - keys = new ArrayList<>(initSize); - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** {@inheritDoc} */ - @Override public UUID nodeId() { - return nodeId; - } - - /** {@inheritDoc} */ - @Override public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** {@inheritDoc} */ - @Override public UUID subjectId() { - return subjId; - } - - /** {@inheritDoc} */ - @Override public int taskNameHash() { - return taskNameHash; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** {@inheritDoc} */ - @Override public boolean fastMap() { - return fastMap; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion updateVersion() { - return updateVer; - } - - /** {@inheritDoc} */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** {@inheritDoc} */ - @Override public boolean topologyLocked() { - return topLocked; - } - - /** {@inheritDoc} */ - @Override public boolean clientRequest() { - return clientReq; - } - - /** {@inheritDoc} */ - @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** {@inheritDoc} */ - @Override public ExpiryPolicy expiry() { - return expiryPlc; - } - - /** {@inheritDoc} */ - @Override public boolean returnValue() { - return retval; - } - - /** {@inheritDoc} */ - @Nullable public CacheEntryPredicate[] filter() { - return filter; - } - - /** {@inheritDoc} */ - @Override public boolean skipStore() { - return skipStore; - } - - /** {@inheritDoc} */ - @Override public boolean keepBinary() { - return keepBinary; - } + public void nodeId(UUID nodeId); /** - * @param key Key to add. - * @param val Optional update value. - * @param conflictTtl Conflict TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param primary If given key is primary on this mapping. + * @return Subject ID. */ - @SuppressWarnings("unchecked") - public void addUpdateEntry(KeyCacheObject key, - @Nullable Object val, - long conflictTtl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - boolean primary) { - EntryProcessor entryProcessor = null; - - if (op == TRANSFORM) { - assert val instanceof EntryProcessor : val; - - entryProcessor = (EntryProcessor)val; - } - - assert val != null || op == DELETE; - - keys.add(key); - - if (entryProcessor != null) { - if (entryProcessors == null) - entryProcessors = new ArrayList<>(initSize); - - entryProcessors.add(entryProcessor); - } - else if (val != null) { - assert val instanceof CacheObject : val; - - if (vals == null) - vals = new ArrayList<>(initSize); - - vals.add((CacheObject)val); - } - - hasPrimary |= primary; - - // In case there is no conflict, do not create the list. - if (conflictVer != null) { - if (conflictVers == null) { - conflictVers = new ArrayList<>(initSize); - - for (int i = 0; i < keys.size() - 1; i++) - conflictVers.add(null); - } - - conflictVers.add(conflictVer); - } - else if (conflictVers != null) - conflictVers.add(null); - - if (conflictTtl >= 0) { - if (conflictTtls == null) { - conflictTtls = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictTtls.add(CU.TTL_NOT_CHANGED); - } - - conflictTtls.add(conflictTtl); - } - - if (conflictExpireTime >= 0) { - if (conflictExpireTimes == null) { - conflictExpireTimes = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - - conflictExpireTimes.add(conflictExpireTime); - } - } - - /** {@inheritDoc} */ - @Override public List keys() { - return keys; - } - - /** {@inheritDoc} */ - @Override public List values() { - return op == TRANSFORM ? entryProcessors : vals; - } - - /** {@inheritDoc} */ - @Override public GridCacheOperation operation() { - return op; - } - - /** {@inheritDoc} */ - @Override @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public CacheObject value(int idx) { - assert op == UPDATE : op; - - return vals.get(idx); - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public EntryProcessor entryProcessor(int idx) { - assert op == TRANSFORM : op; - - return entryProcessors.get(idx); - } - - /** {@inheritDoc} */ - @Override public CacheObject writeValue(int idx) { - if (vals != null) - return vals.get(idx); - - return null; - } - - /** {@inheritDoc} */ - @Override @Nullable public List conflictVersions() { - return conflictVers; - } - - /** {@inheritDoc} */ - @Override @Nullable public GridCacheVersion conflictVersion(int idx) { - if (conflictVers != null) { - assert idx >= 0 && idx < conflictVers.size(); - - return conflictVers.get(idx); - } - - return null; - } - - /** {@inheritDoc} */ - @Override public long conflictTtl(int idx) { - if (conflictTtls != null) { - assert idx >= 0 && idx < conflictTtls.size(); - - return conflictTtls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** {@inheritDoc} */ - @Override public long conflictExpireTime(int idx) { - if (conflictExpireTimes != null) { - assert idx >= 0 && idx < conflictExpireTimes.size(); - - return conflictExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** {@inheritDoc} */ - @Override public boolean hasPrimary() { - return hasPrimary; - } - - /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { - if (this.res == null) { - this.res = res; - - return true; - } - - return false; - } - - /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicUpdateResponse response() { - return res; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - if (filter != null) { - boolean hasFilter = false; - - for (CacheEntryPredicate p : filter) { - if (p != null) { - hasFilter = true; - - p.prepareMarshal(cctx); - } - } - - if (!hasFilter) - filter = null; - } - - if (expiryPlc != null && expiryPlcBytes == null) - expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); - - if (op == TRANSFORM) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - } - else - prepareMarshalCacheObjects(vals, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - if (op == TRANSFORM) { - if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - } - else - finishUnmarshalCacheObjects(vals, cctx, ldr); - - if (filter != null) { - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - - if (expiryPlcBytes != null && expiryPlc == null) - expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeBoolean("clientReq", clientReq)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("conflictTtls", conflictTtls)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("fastMap", fastMap)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeBoolean("hasPrimary", hasPrimary)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) - return false; + public UUID subjectId(); - writer.incrementState(); - - case 17: - if (!writer.writeBoolean("retval", retval)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeBoolean("skipStore", skipStore)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeBoolean("topLocked", topLocked)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("updateVer", updateVer)) - return false; - - writer.incrementState(); - - case 25: - if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) - 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: - clientReq = reader.readBoolean("clientReq"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictExpireTimes = reader.readMessage("conflictExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - conflictTtls = reader.readMessage("conflictTtls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - fastMap = reader.readBoolean("fastMap"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - hasPrimary = reader.readBoolean("hasPrimary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - keys = reader.readCollection("keys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 16: - byte opOrd; - - opOrd = reader.readByte("op"); - - if (!reader.isLastRead()) - return false; - - op = GridCacheOperation.fromOrdinal(opOrd); - - reader.incrementState(); - - case 17: - retval = reader.readBoolean("retval"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 18: - skipStore = reader.readBoolean("skipStore"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 19: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; + /** + * @return Task name hash. + */ + public int taskNameHash(); - reader.incrementState(); + /** + * @return Future version. + */ + public GridCacheVersion futureVersion(); - case 20: - byte syncModeOrd; + /** + * @return Flag indicating whether this is fast-map udpate. + */ + public boolean fastMap(); - syncModeOrd = reader.readByte("syncMode"); + /** + * @return Update version for fast-map request. + */ + public GridCacheVersion updateVersion(); - if (!reader.isLastRead()) - return false; + /** + * @return Topology version. + */ + public AffinityTopologyVersion topologyVersion(); - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + /** + * @return Topology locked flag. + */ + public boolean topologyLocked(); - reader.incrementState(); + /** + * @return {@code True} if request sent from client node. + */ + public boolean clientRequest(); - case 21: - taskNameHash = reader.readInt("taskNameHash"); + /** + * @return Cache write synchronization mode. + */ + public CacheWriteSynchronizationMode writeSynchronizationMode(); - if (!reader.isLastRead()) - return false; + /** + * @return Expiry policy. + */ + public ExpiryPolicy expiry(); - reader.incrementState(); + /** + * @return Return value flag. + */ + public boolean returnValue(); - case 22: - topLocked = reader.readBoolean("topLocked"); + /** + * @return Filter. + */ + @Nullable public CacheEntryPredicate[] filter(); - if (!reader.isLastRead()) - return false; + /** + * @return Skip write-through to a persistent storage. + */ + public boolean skipStore(); - reader.incrementState(); + /** + * @return Keep binary flag. + */ + public boolean keepBinary(); - case 23: - topVer = reader.readMessage("topVer"); + /** + * @return Keys for this update request. + */ + public List keys(); - if (!reader.isLastRead()) - return false; + /** + * @return Values for this update request. + */ + public List values(); - reader.incrementState(); + /** + * @return Update operation. + */ + public GridCacheOperation operation(); - case 24: - updateVer = reader.readMessage("updateVer"); + /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments(); - if (!reader.isLastRead()) - return false; + /** + * @param idx Key index. + * @return Value. + */ + public CacheObject value(int idx); - reader.incrementState(); + /** + * @param idx Key index. + * @return Entry processor. + */ + public EntryProcessor entryProcessor(int idx); - case 25: - vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + /** + * @param idx Index to get. + * @return Write value - either value, or transform closure. + */ + public CacheObject writeValue(int idx); - if (!reader.isLastRead()) - return false; + /** + * @return Conflict versions. + */ + @Nullable public List conflictVersions(); - reader.incrementState(); + /** + * @param idx Index. + * @return Conflict version. + */ + @Nullable public GridCacheVersion conflictVersion(int idx); - } + /** + * @param idx Index. + * @return Conflict TTL. + */ + public long conflictTtl(int idx); - return reader.afterMessageRead(GridNearAtomicUpdateRequest.class); - } + /** + * @param idx Index. + * @return Conflict expire time. + */ + public long conflictExpireTime(int idx); - /** {@inheritDoc} */ - @Override public byte directType() { - return 40; - } + /** + * @return Flag indicating whether this request contains primary keys. + */ + public boolean hasPrimary(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 26; - } + /** + * @param res Response. + * @return {@code True} if current response was {@code null}. + */ + public boolean onResponse(GridNearAtomicUpdateResponse res); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicUpdateRequest.class, this, "filter", Arrays.toString(filter), - "parent", super.toString()); - } + /** + * @return Response. + */ + @Nullable public GridNearAtomicUpdateResponse response(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java deleted file mode 100644 index 8ddb181faea55..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequestBase.java +++ /dev/null @@ -1,199 +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.atomic; - -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.KeyCacheObject; -import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.jetbrains.annotations.Nullable; - -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.processor.EntryProcessor; -import java.util.List; -import java.util.UUID; - -/** - * Base interface for near atomic update requests. - */ -public interface GridNearAtomicUpdateRequestBase { - /** - * @return Message ID. - */ - public long messageId(); - - /** - * @return Mapped node ID. - */ - public UUID nodeId(); - - /** - * @param nodeId Node ID. - */ - public void nodeId(UUID nodeId); - - /** - * @return Subject ID. - */ - public UUID subjectId(); - - /** - * @return Task name hash. - */ - public int taskNameHash(); - - /** - * @return Future version. - */ - public GridCacheVersion futureVersion(); - - /** - * @return Flag indicating whether this is fast-map udpate. - */ - public boolean fastMap(); - - /** - * @return Update version for fast-map request. - */ - public GridCacheVersion updateVersion(); - - /** - * @return Topology version. - */ - public AffinityTopologyVersion topologyVersion(); - - /** - * @return Topology locked flag. - */ - public boolean topologyLocked(); - - /** - * @return {@code True} if request sent from client node. - */ - public boolean clientRequest(); - - /** - * @return Cache write synchronization mode. - */ - public CacheWriteSynchronizationMode writeSynchronizationMode(); - - /** - * @return Expiry policy. - */ - public ExpiryPolicy expiry(); - - /** - * @return Return value flag. - */ - public boolean returnValue(); - - /** - * @return Filter. - */ - @Nullable public CacheEntryPredicate[] filter(); - - /** - * @return Skip write-through to a persistent storage. - */ - public boolean skipStore(); - - /** - * @return Keep binary flag. - */ - public boolean keepBinary(); - - /** - * @return Keys for this update request. - */ - public List keys(); - - /** - * @return Values for this update request. - */ - public List values(); - - /** - * @return Update operation. - */ - public GridCacheOperation operation(); - - /** - * @return Optional arguments for entry processor. - */ - @Nullable public Object[] invokeArguments(); - - /** - * @param idx Key index. - * @return Value. - */ - public CacheObject value(int idx); - - /** - * @param idx Key index. - * @return Entry processor. - */ - public EntryProcessor entryProcessor(int idx); - - /** - * @param idx Index to get. - * @return Write value - either value, or transform closure. - */ - public CacheObject writeValue(int idx); - - /** - * @return Conflict versions. - */ - @Nullable public List conflictVersions(); - - /** - * @param idx Index. - * @return Conflict version. - */ - @Nullable public GridCacheVersion conflictVersion(int idx); - - /** - * @param idx Index. - * @return Conflict TTL. - */ - public long conflictTtl(int idx); - - /** - * @param idx Index. - * @return Conflict expire time. - */ - public long conflictExpireTime(int idx); - - /** - * @return Flag indicating whether this request contains primary keys. - */ - public boolean hasPrimary(); - - /** - * @param res Response. - * @return {@code True} if current response was {@code null}. - */ - public boolean onResponse(GridNearAtomicUpdateResponse res); - - /** - * @return Response. - */ - @Nullable public GridNearAtomicUpdateResponse response(); -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 22b9504007b8c..63c073d56be1b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -45,7 +45,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestBase; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx; @@ -127,7 +127,7 @@ public void dht(GridDhtAtomicCache dht) { * @param res Update response. */ public void processNearAtomicUpdateResponse( - GridNearAtomicUpdateRequestBase req, + GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res ) { if (F.size(res.failedKeys()) == req.keys().size()) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java index cda86ba765a72..50a6114d1195a 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java @@ -29,7 +29,7 @@ import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiException; @@ -138,7 +138,7 @@ protected void checkMessages(boolean clientMode, TestCommunicationSpi commSpi = (TestCommunicationSpi)grid(0).configuration().getCommunicationSpi(); - commSpi.registerMessage(GridNearAtomicUpdateRequest.class); + commSpi.registerMessage(GridNearAtomicMultipleUpdateRequest.class); commSpi.registerMessage(GridNearAtomicSingleUpdateRequest.class); commSpi.registerMessage(GridDhtAtomicUpdateRequest.class); @@ -199,7 +199,7 @@ protected void checkMessages(boolean clientMode, * @return Count. */ private int nearRequestsCount(TestCommunicationSpi commSpi) { - return commSpi.messageCount(GridNearAtomicUpdateRequest.class) + + return commSpi.messageCount(GridNearAtomicMultipleUpdateRequest.class) + commSpi.messageCount(GridNearAtomicSingleUpdateRequest.class); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java index 024ff2f7e4699..43a111a61af5a 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java @@ -19,7 +19,7 @@ import org.apache.ignite.cache.CacheAtomicityMode; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; /** * Stopped node when client operations are executing. @@ -32,7 +32,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPut() throws Exception { - bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); @@ -40,7 +40,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPutBatch() throws Exception { - bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); @@ -48,7 +48,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPutAsync() throws Exception { - bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); @@ -56,7 +56,7 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testRemove() throws Exception { - bannedMsg.set(GridNearAtomicUpdateRequest.class); + bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); super.testPut(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index 8182b33212a08..49686fc87f300 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -62,8 +62,8 @@ import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequestBase; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; @@ -233,10 +233,10 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -278,7 +278,7 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, map.put(i, i + 1); // Block messages requests for single node. - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); putFut = GridTestUtils.runAsync(new Callable() { @@ -366,16 +366,16 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite2.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite2.localNode().id()); - spi.record(GridNearAtomicUpdateRequest.class, GridNearAtomicSingleUpdateRequest.class); + spi.record(GridNearAtomicMultipleUpdateRequest.class, GridNearAtomicSingleUpdateRequest.class); final IgniteCache cache = ignite3.cache(null); @@ -412,7 +412,7 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio assertEquals(3, msgs.size()); for (Object msg : msgs) - assertTrue(((GridNearAtomicUpdateRequestBase)msg).clientRequest()); + assertTrue(((GridNearAtomicUpdateRequest)msg).clientRequest()); map.put(primaryKey(ignite0.cache(null)), 3); map.put(primaryKey(ignite1.cache(null)), 4); @@ -469,10 +469,10 @@ private void atomicGetAndPut(CacheAtomicWriteOrderMode writeOrder) throws Except TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java index c3bd369e5d4b7..0e7755bee8e9c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java @@ -478,7 +478,7 @@ private boolean delayMessage(GridIoMessage msg) { Object origMsg = msg.message(); return delay && ( - (origMsg instanceof GridNearAtomicUpdateRequest) || + (origMsg instanceof GridNearAtomicMultipleUpdateRequest) || (origMsg instanceof GridNearAtomicSingleUpdateRequest) || (origMsg instanceof GridDhtAtomicUpdateRequest) ); From a18c352748a86ac9e48885f1b6ae93ff9ed4f4dd Mon Sep 17 00:00:00 2001 From: vozerov-gridgain Date: Fri, 5 Feb 2016 10:09:48 +0300 Subject: [PATCH 16/34] IGNITE-2523: Minors. --- .../dht/atomic/GridNearAtomicUpdateFuture.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 879f9f390cb82..c1dab93f9e25e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -38,6 +38,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; @@ -465,13 +466,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (log.isDebugEnabled()) log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - if (req instanceof GridNearAtomicMultipleUpdateRequest) - cctx.io().send(req.nodeId(), (GridNearAtomicMultipleUpdateRequest)req, cctx.ioPolicy()); - else { - assert req instanceof GridNearAtomicSingleUpdateRequest; - - cctx.io().send(req.nodeId(), (GridNearAtomicSingleUpdateRequest)req, cctx.ioPolicy()); - } + cctx.io().send(req.nodeId(), (GridCacheMessage)req, cctx.ioPolicy()); if (syncMode == FULL_ASYNC) onDone(new GridCacheReturn(cctx, true, true, null, true)); From 649d7cd3dc87f09c9fa0c4476bbc65ab2728824d Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 5 Feb 2016 13:47:15 +0300 Subject: [PATCH 17/34] ignite-2533 : Fixed deadlock on topology error. --- .../distributed/near/GridNearLockFuture.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) 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 d5a476ddc6e6b..bf9976873d501 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 @@ -517,7 +517,7 @@ private void onResult(UUID nodeId, GridNearLockResponse res, GridNearLockMapping if (res.error() instanceof GridCacheLockTimeoutException) onDone(false); else - onError(res.error()); + onDone(res.error()); return; } @@ -537,7 +537,7 @@ private void onResult(UUID nodeId, GridNearLockResponse res, GridNearLockMapping remap(); } catch (IgniteCheckedException e) { - onError(e); + onDone(e); } finally { cctx.shared().txContextReset(); @@ -704,9 +704,7 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); proceedMapping(); } catch (IgniteCheckedException ex) { - onError(ex); - - onDone(false); + onDone(false, ex); } } @@ -738,7 +736,7 @@ private boolean filter(GridCacheEntryEx cached) { return true; } catch (IgniteCheckedException e) { - onError(e); + onDone(e); return false; } @@ -913,7 +911,7 @@ void map() { Throwable err = fut.validateCache(cctx); if (err != null) { - onError(err); + onDone(err); return; } @@ -959,7 +957,7 @@ synchronized void mapOnTopology(final boolean remap) { Throwable err = fut.validateCache(cctx); if (err != null) { - onError(err); + onDone(err); return; } @@ -991,7 +989,7 @@ synchronized void mapOnTopology(final boolean remap) { mapOnTopology(remap); } catch (IgniteCheckedException e) { - onError(e); + onDone(e); } finally { cctx.shared().txContextReset(); @@ -1010,7 +1008,7 @@ private synchronized void checkComplete() { return; if (err != null) - onDone(false, err); + onDone(err); if (!hasPending()) onDone(true); @@ -1270,7 +1268,7 @@ private void map(Iterable keys, boolean remap, boolean topLocked checkComplete(); } catch (IgniteCheckedException ex) { - onError(ex); + onDone(ex); } } @@ -1338,7 +1336,7 @@ private void proceedMapping0() onResult(node.id(), future.get()); } catch (IgniteCheckedException e) { - onError(e); + onDone(e); } } } @@ -1358,7 +1356,7 @@ private void proceedMapping0() cctx.io().send(node, req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { - onError(ex); + onDone(ex); } } else { @@ -1375,7 +1373,7 @@ private void proceedMapping0() onError(newTopologyException(ex, node.id())); } catch (IgniteCheckedException e) { - onError(e); + onDone(e); } } }); From dfdd2f4f907651a86da6fd52f18d2f189f65279d Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Mon, 8 Feb 2016 17:23:02 +0300 Subject: [PATCH 18/34] ignite-2523 : Created SingleUpdateResponse --- .../communication/GridIoMessageFactory.java | 10 +- .../processors/cache/GridCacheIoManager.java | 10 +- .../dht/atomic/GridDhtAtomicCache.java | 38 +- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 8 +- .../GridNearAtomicMultipleUpdateRequest.java | 6 +- .../GridNearAtomicMultipleUpdateResponse.java | 640 +++++++++++++++++ .../GridNearAtomicSingleUpdateRequest.java | 6 +- .../GridNearAtomicSingleUpdateResponse.java | 641 ++++++++++++++++++ .../atomic/GridNearAtomicUpdateFuture.java | 22 +- .../atomic/GridNearAtomicUpdateRequest.java | 4 +- .../atomic/GridNearAtomicUpdateResponse.java | 616 ++--------------- .../distributed/near/GridNearAtomicCache.java | 4 +- .../IgniteClientReconnectCacheTest.java | 4 +- .../IgniteClientReconnectCollectionsTest.java | 6 +- 14 files changed, 1382 insertions(+), 633 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.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 88e34c98c0081..4d769afd17d33 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 @@ -68,9 +68,10 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicDeferredUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateResponse; 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.GridDhtPartitionDemandMessage; @@ -368,7 +369,7 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 41: - msg = new GridNearAtomicUpdateResponse(); + msg = new GridNearAtomicMultipleUpdateResponse(); break; @@ -732,6 +733,11 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; + case -24: + msg = new GridNearAtomicSingleUpdateResponse(); + + break; + // [-3..119] [124] - this // [120..123] - DR // [-4..-22] - SQL 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 8a8f1616b2de6..ea972774641f2 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 @@ -46,7 +46,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; 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.near.GridNearGetRequest; @@ -412,7 +412,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC case 40: { GridNearAtomicMultipleUpdateRequest req = (GridNearAtomicMultipleUpdateRequest)msg; - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse( + GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse( ctx.cacheId(), nodeId, req.futureVersion(), @@ -443,7 +443,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 45: { - processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander. + processMessage(nodeId, msg, c);// Will be handled by Rebalance Demander. } break; @@ -544,7 +544,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 114: { - processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander. + processMessage(nodeId, msg, c);// Will be handled by Rebalance Demander. } break; @@ -590,7 +590,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC case -23: { GridNearAtomicSingleUpdateRequest req = (GridNearAtomicSingleUpdateRequest)msg; - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse( + GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse( ctx.cacheId(), nodeId, req.futureVersion(), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 55db70acb1e0c..b0504db488823 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -139,7 +139,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { Integer.getInteger(IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT, 500); /** Update reply closure. */ - private CI2 updateReplyClos; + private CI2 updateReplyClos; /** Pending */ private ConcurrentMap pendingResponses = new ConcurrentHashMap8<>(); @@ -192,9 +192,9 @@ public GridDhtAtomicCache(GridCacheContext ctx, GridCacheConcurrentMap map } }); - updateReplyClos = new CI2() { + updateReplyClos = new CI2() { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { if (ctx.config().getAtomicWriteOrderMode() == CLOCK) { assert req.writeSynchronizationMode() != FULL_ASYNC : req; @@ -262,8 +262,8 @@ else if (res.error() != null) { } }); - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicUpdateResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicMultipleUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { processNearAtomicUpdateResponse(nodeId, res); } }); @@ -1311,7 +1311,7 @@ else if (!skipVals && ctx.config().isStatisticsEnabled()) public void updateAllAsyncInternal( final UUID nodeId, final GridNearAtomicUpdateRequest req, - final CI2 completionCb + final CI2 completionCb ) { IgniteInternalFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); @@ -1336,9 +1336,9 @@ public void updateAllAsyncInternal( public void updateAllAsyncInternal0( UUID nodeId, GridNearAtomicUpdateRequest req, - CI2 completionCb + CI2 completionCb ) { - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), + GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), ctx.deploymentEnabled()); List keys = req.keys(); @@ -1559,11 +1559,11 @@ private UpdateBatchResult updateWithBatch( ClusterNode node, boolean hasNear, GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res, + GridNearAtomicMultipleUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -1975,11 +1975,11 @@ private UpdateSingleResult updateSingle( ClusterNode node, boolean hasNear, GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res, + GridNearAtomicMultipleUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -2214,9 +2214,9 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable Collection rmvKeys, @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, final GridNearAtomicUpdateRequest req, - final GridNearAtomicUpdateResponse res, + final GridNearAtomicMultipleUpdateResponse res, boolean replicate, UpdateBatchResult batchRes, String taskName, @@ -2594,7 +2594,7 @@ private void unlockEntries(Collection locked, AffinityTopolog * @return {@code True} if filter evaluation succeeded. */ private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res) { + GridNearAtomicMultipleUpdateResponse res) { try { return ctx.isAllLocked(entry, req.filter()); } @@ -2688,8 +2688,8 @@ else if (req.operation() == UPDATE) { @Nullable private GridDhtAtomicUpdateFuture createDhtFuture( GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, - GridNearAtomicUpdateResponse updateRes, - CI2 completionCb, + GridNearAtomicMultipleUpdateResponse updateRes, + CI2 completionCb, boolean force ) { if (!force) { @@ -2734,7 +2734,7 @@ private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateReq * @param res Near atomic update response. */ @SuppressWarnings("unchecked") - private void processNearAtomicUpdateResponse(UUID nodeId, GridNearAtomicUpdateResponse res) { + private void processNearAtomicUpdateResponse(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { if (log.isDebugEnabled()) log.debug("Processing near atomic update response [nodeId=" + nodeId + ", res=" + res + ']'); @@ -2944,7 +2944,7 @@ private void processDhtAtomicDeferredUpdateResponse(UUID nodeId, GridDhtAtomicDe * @param nodeId Originating node ID. * @param res Near update response. */ - private void sendNearUpdateReply(UUID nodeId, GridNearAtomicUpdateResponse res) { + private void sendNearUpdateReply(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { try { ctx.io().send(nodeId, res, ctx.ioPolicy()); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 3a31700dcedfc..68c639d9a7dfb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -77,7 +77,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement /** Completion callback. */ @GridToStringExclude - private final CI2 completionCb; + private final CI2 completionCb; /** Mappings. */ @GridToStringInclude @@ -90,7 +90,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement private final GridNearAtomicUpdateRequest updateReq; /** Update response. */ - private final GridNearAtomicUpdateResponse updateRes; + private final GridNearAtomicMultipleUpdateResponse updateRes; /** Future keys. */ private final Collection keys; @@ -110,10 +110,10 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, - GridNearAtomicUpdateResponse updateRes + GridNearAtomicMultipleUpdateResponse updateRes ) { this.cctx = cctx; this.writeVer = writeVer; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java index 650d350f76a84..6f109befb5c2b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java @@ -157,7 +157,7 @@ public class GridNearAtomicMultipleUpdateRequest extends GridCacheMessage /** */ @GridDirectTransient - private GridNearAtomicUpdateResponse res; + private GridNearAtomicMultipleUpdateResponse res; /** Maximum possible size of inner collections. */ @GridDirectTransient @@ -502,7 +502,7 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { + @Override public boolean onResponse(GridNearAtomicMultipleUpdateResponse res) { if (this.res == null) { this.res = res; @@ -513,7 +513,7 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicUpdateResponse response() { + @Override @Nullable public GridNearAtomicMultipleUpdateResponse response() { return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java new file mode 100644 index 0000000000000..d22acc4ce7e5f --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java @@ -0,0 +1,640 @@ +/* + * 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.atomic; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; +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.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +import org.apache.ignite.internal.processors.cache.GridCacheReturn; +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; +import org.apache.ignite.internal.util.GridLongList; +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; +import org.jetbrains.annotations.Nullable; + +/** + * DHT atomic cache near update response. + */ +public class GridNearAtomicMultipleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridNearAtomicUpdateResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Cache message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID this reply should be sent to. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Update error. */ + @GridDirectTransient + private volatile IgniteCheckedException err; + + /** Serialized error. */ + private byte[] errBytes; + + /** Return value. */ + @GridToStringInclude + private GridCacheReturn ret; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private volatile Collection failedKeys; + + /** Keys that should be remapped. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List remapKeys; + + /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearValsIdxs; + + /** Indexes of keys for which update was skipped (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearSkipIdxs; + + /** Values generated on primary node which should be put to originating node's near cache. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Version generated on primary node to be used for originating node's near cache update. */ + private GridCacheVersion nearVer; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridNearAtomicMultipleUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param nodeId Node ID this reply should be sent to. + * @param futVer Future version. + * @param addDepInfo Deployment info flag. + */ + public GridNearAtomicMultipleUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID this response should be sent to. + */ + @Override public UUID nodeId() { + return nodeId; + } + + /** + * @param nodeId Node ID. + */ + @Override public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } + + /** + * @return Future version. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + @Override public void error(IgniteCheckedException err){ + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Collection of failed keys. + */ + @Override public Collection failedKeys() { + return failedKeys; + } + + /** + * @return Return value. + */ + @Override public GridCacheReturn returnValue() { + return ret; + } + + /** + * @param ret Return value. + */ + @Override @SuppressWarnings("unchecked") + public void returnValue(GridCacheReturn ret) { + this.ret = ret; + } + + /** + * @param remapKeys Remap keys. + */ + @Override public void remapKeys(List remapKeys) { + this.remapKeys = remapKeys; + } + + /** + * @return Remap keys. + */ + @Override public Collection remapKeys() { + return remapKeys; + } + + /** + * Adds value to be put in near cache on originating node. + * + * @param keyIdx Key index. + * @param val Value. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + @Override public void addNearValue(int keyIdx, + @Nullable CacheObject val, + long ttl, + long expireTime) { + if (nearValsIdxs == null) { + nearValsIdxs = new ArrayList<>(); + nearVals = new ArrayList<>(); + } + + addNearTtl(keyIdx, ttl, expireTime); + + nearValsIdxs.add(keyIdx); + nearVals.add(val); + } + + /** + * @param keyIdx Key index. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + @Override @SuppressWarnings("ForLoopReplaceableByForEach") + public void addNearTtl(int keyIdx, long ttl, long expireTime) { + if (ttl >= 0) { + if (nearTtls == null) { + nearTtls = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearTtls.add(-1L); + } + } + + if (nearTtls != null) + nearTtls.add(ttl); + + if (expireTime >= 0) { + if (nearExpireTimes == null) { + nearExpireTimes = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearExpireTimes.add(-1); + } + } + + if (nearExpireTimes != null) + nearExpireTimes.add(expireTime); + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + @Override public long nearExpireTime(int idx) { + if (nearExpireTimes != null) { + assert idx >= 0 && idx < nearExpireTimes.size(); + + return nearExpireTimes.get(idx); + } + + return -1L; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + @Override public long nearTtl(int idx) { + if (nearTtls != null) { + assert idx >= 0 && idx < nearTtls.size(); + + return nearTtls.get(idx); + } + + return -1L; + } + + /** + * @param nearVer Version generated on primary node to be used for originating node's near cache update. + */ + @Override public void nearVersion(GridCacheVersion nearVer) { + this.nearVer = nearVer; + } + + /** + * @return Version generated on primary node to be used for originating node's near cache update. + */ + @Override public GridCacheVersion nearVersion() { + return nearVer; + } + + /** + * @param keyIdx Index of key for which update was skipped + */ + @Override public void addSkippedIndex(int keyIdx) { + if (nearSkipIdxs == null) + nearSkipIdxs = new ArrayList<>(); + + nearSkipIdxs.add(keyIdx); + + addNearTtl(keyIdx, -1L, -1L); + } + + /** + * @return Indexes of keys for which update was skipped + */ + @Override @Nullable public List skippedIndexes() { + return nearSkipIdxs; + } + + /** + * @return Indexes of keys for which values were generated on primary node. + */ + @Override @Nullable public List nearValuesIndexes() { + return nearValsIdxs; + } + + /** + * @param idx Index. + * @return Value generated on primary node which should be put to originating node's near cache. + */ + @Override @Nullable public CacheObject nearValue(int idx) { + return nearVals.get(idx); + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + @Override public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ConcurrentLinkedQueue<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + */ + @Override public synchronized void addFailedKeys(Collection keys, Throwable e) { + if (keys != null) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); + + failedKeys.addAll(keys); + } + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + * @param ctx Context. + */ + @Override public synchronized void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); + + failedKeys.addAll(keys); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** {@inheritDoc} + * @param ctx*/ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (err != null && errBytes == null) + errBytes = ctx.marshaller().marshal(err); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(failedKeys, cctx); + + prepareMarshalCacheObjects(remapKeys, cctx); + + prepareMarshalCacheObjects(nearVals, cctx); + + if (ret != null) + ret.prepareMarshal(cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(remapKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearVals, cctx, ldr); + + if (ret != null) + ret.finishUnmarshal(cctx, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeMessage("nearTtls", nearTtls)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("nearVer", nearVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeMessage("ret", ret)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + nearExpireTimes = reader.readMessage("nearExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + nearTtls = reader.readMessage("nearTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + nearVer = reader.readMessage("nearVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + ret = reader.readMessage("ret"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearAtomicMultipleUpdateResponse.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 41; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 14; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicMultipleUpdateResponse.class, this, "parent"); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 1e981afd9a212..87140100bdd79 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -149,7 +149,7 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage /** */ @GridDirectTransient - private GridNearAtomicUpdateResponse res; + private GridNearAtomicMultipleUpdateResponse res; /** * Empty constructor required by {@link Externalizable}. @@ -427,7 +427,7 @@ else if (val != null) { } /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { + @Override public boolean onResponse(GridNearAtomicMultipleUpdateResponse res) { if (this.res == null) { this.res = res; @@ -438,7 +438,7 @@ else if (val != null) { } /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicUpdateResponse response() { + @Override @Nullable public GridNearAtomicMultipleUpdateResponse response() { return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java new file mode 100644 index 0000000000000..581c33b8f58b4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java @@ -0,0 +1,641 @@ +/* + * 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.atomic; + +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.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +import org.apache.ignite.internal.processors.cache.GridCacheReturn; +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; +import org.apache.ignite.internal.util.GridLongList; +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; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class GridNearAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridNearAtomicUpdateResponse { + + /** */ + private static final long serialVersionUID = 0L; + + /** Cache message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID this reply should be sent to. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Update error. */ + @GridDirectTransient + private volatile IgniteCheckedException err; + + /** Serialized error. */ + private byte[] errBytes; + + /** Return value. */ + @GridToStringInclude + private GridCacheReturn ret; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private volatile Collection failedKeys; + + /** Keys that should be remapped. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List remapKeys; + + /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearValsIdxs; + + /** Indexes of keys for which update was skipped (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearSkipIdxs; + + /** Values generated on primary node which should be put to originating node's near cache. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Version generated on primary node to be used for originating node's near cache update. */ + private GridCacheVersion nearVer; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridNearAtomicSingleUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param nodeId Node ID this reply should be sent to. + * @param futVer Future version. + * @param addDepInfo Deployment info flag. + */ + public GridNearAtomicSingleUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID this response should be sent to. + */ + @Override public UUID nodeId() { + return nodeId; + } + + /** + * @param nodeId Node ID. + */ + @Override public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } + + /** + * @return Future version. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + @Override public void error(IgniteCheckedException err) { + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Collection of failed keys. + */ + @Override public Collection failedKeys() { + return failedKeys; + } + + /** + * @return Return value. + */ + @Override public GridCacheReturn returnValue() { + return ret; + } + + /** + * @param ret Return value. + */ + @Override @SuppressWarnings("unchecked") + public void returnValue(GridCacheReturn ret) { + this.ret = ret; + } + + /** + * @param remapKeys Remap keys. + */ + @Override public void remapKeys(List remapKeys) { + this.remapKeys = remapKeys; + } + + /** + * @return Remap keys. + */ + @Override public Collection remapKeys() { + return remapKeys; + } + + /** + * Adds value to be put in near cache on originating node. + * + * @param keyIdx Key index. + * @param val Value. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + @Override public void addNearValue(int keyIdx, + @Nullable CacheObject val, + long ttl, + long expireTime) { + if (nearValsIdxs == null) { + nearValsIdxs = new ArrayList<>(); + nearVals = new ArrayList<>(); + } + + addNearTtl(keyIdx, ttl, expireTime); + + nearValsIdxs.add(keyIdx); + nearVals.add(val); + } + + /** + * @param keyIdx Key index. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + @Override @SuppressWarnings("ForLoopReplaceableByForEach") + public void addNearTtl(int keyIdx, long ttl, long expireTime) { + if (ttl >= 0) { + if (nearTtls == null) { + nearTtls = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearTtls.add(-1L); + } + } + + if (nearTtls != null) + nearTtls.add(ttl); + + if (expireTime >= 0) { + if (nearExpireTimes == null) { + nearExpireTimes = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearExpireTimes.add(-1); + } + } + + if (nearExpireTimes != null) + nearExpireTimes.add(expireTime); + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + @Override public long nearExpireTime(int idx) { + if (nearExpireTimes != null) { + assert idx >= 0 && idx < nearExpireTimes.size(); + + return nearExpireTimes.get(idx); + } + + return -1L; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + @Override public long nearTtl(int idx) { + if (nearTtls != null) { + assert idx >= 0 && idx < nearTtls.size(); + + return nearTtls.get(idx); + } + + return -1L; + } + + /** + * @param nearVer Version generated on primary node to be used for originating node's near cache update. + */ + @Override public void nearVersion(GridCacheVersion nearVer) { + this.nearVer = nearVer; + } + + /** + * @return Version generated on primary node to be used for originating node's near cache update. + */ + @Override public GridCacheVersion nearVersion() { + return nearVer; + } + + /** + * @param keyIdx Index of key for which update was skipped + */ + @Override public void addSkippedIndex(int keyIdx) { + if (nearSkipIdxs == null) + nearSkipIdxs = new ArrayList<>(); + + nearSkipIdxs.add(keyIdx); + + addNearTtl(keyIdx, -1L, -1L); + } + + /** + * @return Indexes of keys for which update was skipped + */ + @Override @Nullable public List skippedIndexes() { + return nearSkipIdxs; + } + + /** + * @return Indexes of keys for which values were generated on primary node. + */ + @Override @Nullable public List nearValuesIndexes() { + return nearValsIdxs; + } + + /** + * @param idx Index. + * @return Value generated on primary node which should be put to originating node's near cache. + */ + @Override @Nullable public CacheObject nearValue(int idx) { + return nearVals.get(idx); + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + @Override public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ConcurrentLinkedQueue<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + */ + @Override public synchronized void addFailedKeys(Collection keys, Throwable e) { + if (keys != null) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); + + failedKeys.addAll(keys); + } + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + * @param ctx Context. + */ + @Override public synchronized void addFailedKeys(Collection keys, Throwable e, + GridCacheContext ctx) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); + + failedKeys.addAll(keys); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** {@inheritDoc} + * @param ctx*/ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (err != null && errBytes == null) + errBytes = ctx.marshaller().marshal(err); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(failedKeys, cctx); + + prepareMarshalCacheObjects(remapKeys, cctx); + + prepareMarshalCacheObjects(nearVals, cctx); + + if (ret != null) + ret.prepareMarshal(cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(remapKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearVals, cctx, ldr); + + if (ret != null) + ret.finishUnmarshal(cctx, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeMessage("nearTtls", nearTtls)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("nearVer", nearVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeMessage("ret", ret)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + nearExpireTimes = reader.readMessage("nearExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + nearTtls = reader.readMessage("nearTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + nearVer = reader.readMessage("nearVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + ret = reader.readMessage("ret"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearAtomicMultipleUpdateResponse.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return -24; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 14; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicSingleUpdateResponse.class, this, "parent"); + } + +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index c1dab93f9e25e..68ee67bb23120 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -339,7 +339,7 @@ public void map() { * @param nodeId Node ID. * @param res Update response. */ - public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { + public void onResult(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { state.onResult(nodeId, res, false); } @@ -349,7 +349,7 @@ public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { * @param req Update request. * @param res Update response. */ - private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { + private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { assert nearEnabled; if (res.remapKeys() != null || !req.hasPrimary()) @@ -454,9 +454,9 @@ private Collection mapKey( private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, - new CI2() { + new CI2() { @Override public void apply(GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res) { + GridNearAtomicMultipleUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -510,8 +510,8 @@ private void doUpdate(Map mappings) { if (locUpdate != null) { cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, - new CI2() { - @Override public void apply(GridNearAtomicMultipleUpdateRequest req, GridNearAtomicUpdateResponse res) { + new CI2() { + @Override public void apply(GridNearAtomicMultipleUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -570,7 +570,7 @@ private class UpdateState { * @param nodeId Left node ID. */ void onNodeLeft(UUID nodeId) { - GridNearAtomicUpdateResponse res = null; + GridNearAtomicMultipleUpdateResponse res = null; synchronized (this) { GridNearAtomicUpdateRequest req; @@ -581,7 +581,7 @@ void onNodeLeft(UUID nodeId) { req = mappings != null ? mappings.get(nodeId) : null; if (req != null && req.response() == null) { - res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), nodeId, req.futureVersion(), cctx.deploymentEnabled()); @@ -605,7 +605,7 @@ void onNodeLeft(UUID nodeId) { * @param nodeErr {@code True} if response was created on node failure. */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) - void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { + void onResult(UUID nodeId, GridNearAtomicMultipleUpdateResponse res, boolean nodeErr) { GridNearAtomicUpdateRequest req; AffinityTopologyVersion remapTopVer = null; @@ -737,7 +737,7 @@ else if (res.error() != null) { if (rcvAll && nearEnabled) { if (mappings != null) { for (GridNearAtomicMultipleUpdateRequest req0 : mappings.values()) { - GridNearAtomicUpdateResponse res0 = req0.response(); + GridNearAtomicMultipleUpdateResponse res0 = req0.response(); assert res0 != null : req0; @@ -812,7 +812,7 @@ else if (!nodeErr) */ void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { synchronized (this) { - GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), req.nodeId(), req.futureVersion(), cctx.deploymentEnabled()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 960add7eb0ba3..c1977bfd2d92e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -190,10 +190,10 @@ public interface GridNearAtomicUpdateRequest { * @param res Response. * @return {@code True} if current response was {@code null}. */ - public boolean onResponse(GridNearAtomicUpdateResponse res); + public boolean onResponse(GridNearAtomicMultipleUpdateResponse res); /** * @return Response. */ - @Nullable public GridNearAtomicUpdateResponse response(); + @Nullable public GridNearAtomicMultipleUpdateResponse response(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java index 3e3ac29c09e28..51d388c41b06b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java @@ -17,624 +17,86 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; 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.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheReturn; 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; -import org.apache.ignite.internal.util.GridLongList; -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; import org.jetbrains.annotations.Nullable; -/** - * DHT atomic cache near update response. - */ -public class GridNearAtomicUpdateResponse extends GridCacheMessage implements GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Cache message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID this reply should be sent to. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Update error. */ - @GridDirectTransient - private volatile IgniteCheckedException err; - - /** Serialized error. */ - private byte[] errBytes; - - /** Return value. */ - @GridToStringInclude - private GridCacheReturn ret; - - /** Failed keys. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private volatile Collection failedKeys; - - /** Keys that should be remapped. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List remapKeys; - - /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearValsIdxs; - - /** Indexes of keys for which update was skipped (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearSkipIdxs; - - /** Values generated on primary node which should be put to originating node's near cache. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; - - /** Version generated on primary node to be used for originating node's near cache update. */ - private GridCacheVersion nearVer; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridNearAtomicUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param nodeId Node ID this reply should be sent to. - * @param futVer Future version. - * @param addDepInfo Deployment info flag. - */ - public GridNearAtomicUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { - assert futVer != null; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID this response should be sent to. - */ - public UUID nodeId() { - return nodeId; - } - - /** - * @param nodeId Node ID. - */ - public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** - * @return Future version. - */ - public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - public void error(IgniteCheckedException err){ - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Collection of failed keys. - */ - public Collection failedKeys() { - return failedKeys; - } - - /** - * @return Return value. - */ - public GridCacheReturn returnValue() { - return ret; - } - - /** - * @param ret Return value. - */ - @SuppressWarnings("unchecked") - public void returnValue(GridCacheReturn ret) { - this.ret = ret; - } - - /** - * @param remapKeys Remap keys. - */ - public void remapKeys(List remapKeys) { - this.remapKeys = remapKeys; - } - - /** - * @return Remap keys. - */ - public Collection remapKeys() { - return remapKeys; - } - - /** - * Adds value to be put in near cache on originating node. - * - * @param keyIdx Key index. - * @param val Value. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - public void addNearValue(int keyIdx, - @Nullable CacheObject val, - long ttl, - long expireTime) { - if (nearValsIdxs == null) { - nearValsIdxs = new ArrayList<>(); - nearVals = new ArrayList<>(); - } - - addNearTtl(keyIdx, ttl, expireTime); - - nearValsIdxs.add(keyIdx); - nearVals.add(val); - } - - /** - * @param keyIdx Key index. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - @SuppressWarnings("ForLoopReplaceableByForEach") - public void addNearTtl(int keyIdx, long ttl, long expireTime) { - if (ttl >= 0) { - if (nearTtls == null) { - nearTtls = new GridLongList(16); - - for (int i = 0; i < keyIdx; i++) - nearTtls.add(-1L); - } - } - - if (nearTtls != null) - nearTtls.add(ttl); - - if (expireTime >= 0) { - if (nearExpireTimes == null) { - nearExpireTimes = new GridLongList(16); - - for (int i = 0; i < keyIdx; i++) - nearExpireTimes.add(-1); - } - } - - if (nearExpireTimes != null) - nearExpireTimes.add(expireTime); - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - public long nearExpireTime(int idx) { - if (nearExpireTimes != null) { - assert idx >= 0 && idx < nearExpireTimes.size(); - - return nearExpireTimes.get(idx); - } - - return -1L; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - public long nearTtl(int idx) { - if (nearTtls != null) { - assert idx >= 0 && idx < nearTtls.size(); - - return nearTtls.get(idx); - } - - return -1L; - } - - /** - * @param nearVer Version generated on primary node to be used for originating node's near cache update. - */ - public void nearVersion(GridCacheVersion nearVer) { - this.nearVer = nearVer; - } - - /** - * @return Version generated on primary node to be used for originating node's near cache update. - */ - public GridCacheVersion nearVersion() { - return nearVer; - } - - /** - * @param keyIdx Index of key for which update was skipped - */ - public void addSkippedIndex(int keyIdx) { - if (nearSkipIdxs == null) - nearSkipIdxs = new ArrayList<>(); - - nearSkipIdxs.add(keyIdx); - - addNearTtl(keyIdx, -1L, -1L); - } - - /** - * @return Indexes of keys for which update was skipped - */ - @Nullable public List skippedIndexes() { - return nearSkipIdxs; - } - - /** - * @return Indexes of keys for which values were generated on primary node. - */ - @Nullable public List nearValuesIndexes() { - return nearValsIdxs; - } - - /** - * @param idx Index. - * @return Value generated on primary node which should be put to originating node's near cache. - */ - @Nullable public CacheObject nearValue(int idx) { - return nearVals.get(idx); - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ConcurrentLinkedQueue<>(); - - failedKeys.add(key); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - */ - public synchronized void addFailedKeys(Collection keys, Throwable e) { - if (keys != null) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); - - failedKeys.addAll(keys); - } - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - * @param ctx Context. - */ - public synchronized void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); - - failedKeys.addAll(keys); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (err != null && errBytes == null) - errBytes = ctx.marshaller().marshal(err); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(failedKeys, cctx); - - prepareMarshalCacheObjects(remapKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); - - if (ret != null) - ret.prepareMarshal(cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - - finishUnmarshalCacheObjects(remapKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearVals, cctx, ldr); - - if (ret != null) - ret.finishUnmarshal(cctx, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeMessage("nearTtls", nearTtls)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("nearVer", nearVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeMessage("ret", ret)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.List; +import java.util.UUID; - case 5: - futVer = reader.readMessage("futVer"); +public interface GridNearAtomicUpdateResponse { - if (!reader.isLastRead()) - return false; + int lookupIndex(); - reader.incrementState(); + UUID nodeId(); - case 6: - nearExpireTimes = reader.readMessage("nearExpireTimes"); + void nodeId(UUID nodeId); - if (!reader.isLastRead()) - return false; + GridCacheVersion futureVersion(); - reader.incrementState(); + void error(IgniteCheckedException err); - case 7: - nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); + IgniteCheckedException error(); - if (!reader.isLastRead()) - return false; + Collection failedKeys(); - reader.incrementState(); + GridCacheReturn returnValue(); - case 8: - nearTtls = reader.readMessage("nearTtls"); + @SuppressWarnings("unchecked") void returnValue(GridCacheReturn ret); - if (!reader.isLastRead()) - return false; + void remapKeys(List remapKeys); - reader.incrementState(); + Collection remapKeys(); - case 9: - nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + void addNearValue(int keyIdx, + @Nullable CacheObject val, + long ttl, + long expireTime); - if (!reader.isLastRead()) - return false; + @SuppressWarnings("ForLoopReplaceableByForEach") void addNearTtl(int keyIdx, long ttl, long expireTime); - reader.incrementState(); + long nearExpireTime(int idx); - case 10: - nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); + long nearTtl(int idx); - if (!reader.isLastRead()) - return false; + void nearVersion(GridCacheVersion nearVer); - reader.incrementState(); + GridCacheVersion nearVersion(); - case 11: - nearVer = reader.readMessage("nearVer"); + void addSkippedIndex(int keyIdx); - if (!reader.isLastRead()) - return false; + @Nullable List skippedIndexes(); - reader.incrementState(); + @Nullable List nearValuesIndexes(); - case 12: - remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); + @Nullable CacheObject nearValue(int idx); - if (!reader.isLastRead()) - return false; + void addFailedKey(KeyCacheObject key, Throwable e); - reader.incrementState(); + void addFailedKeys(Collection keys, Throwable e); - case 13: - ret = reader.readMessage("ret"); + void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx); - if (!reader.isLastRead()) - return false; + void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; - reader.incrementState(); + void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; - } + boolean addDeploymentInfo(); - return reader.afterMessageRead(GridNearAtomicUpdateResponse.class); - } + boolean writeTo(ByteBuffer buf, MessageWriter writer); - /** {@inheritDoc} */ - @Override public byte directType() { - return 41; - } + boolean readFrom(ByteBuffer buf, MessageReader reader); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 14; - } + byte directType(); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicUpdateResponse.class, this, "parent"); - } + byte fieldsCount(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 63c073d56be1b..2546691d7bfcc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -45,8 +45,8 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -128,7 +128,7 @@ public void dht(GridDhtAtomicCache dht) { */ public void processNearAtomicUpdateResponse( GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res + GridNearAtomicMultipleUpdateResponse res ) { if (F.size(res.failedKeys()) == req.keys().size()) return; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java index ad6c46f284b74..37937d318427b 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java @@ -49,7 +49,7 @@ import org.apache.ignite.events.Event; import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; @@ -806,7 +806,7 @@ else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) if (syncMode != FULL_ASYNC) { Class cls = (ccfg.getAtomicityMode() == ATOMIC) ? - GridNearAtomicUpdateResponse.class : GridNearTxPrepareResponse.class; + GridNearAtomicMultipleUpdateResponse.class : GridNearTxPrepareResponse.class; log.info("Test cache put [atomicity=" + atomicityMode + ", writeOrder=" + writeOrder + diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java index 100e8de4a4a36..d25ac37025974 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java @@ -26,7 +26,7 @@ import org.apache.ignite.IgniteQueue; import org.apache.ignite.IgniteSet; import org.apache.ignite.configuration.CollectionConfiguration; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse; import org.apache.ignite.testframework.GridTestUtils; @@ -315,7 +315,7 @@ private void setReconnectInProgress(final CollectionConfiguration colCfg) throws BlockTpcCommunicationSpi commSpi = commSpi(srv); if (colCfg.getAtomicityMode() == ATOMIC) - commSpi.blockMessage(GridNearAtomicUpdateResponse.class); + commSpi.blockMessage(GridNearAtomicMultipleUpdateResponse.class); else commSpi.blockMessage(GridNearTxPrepareResponse.class); @@ -457,7 +457,7 @@ private void queueReconnectInProgress(final CollectionConfiguration colCfg) thro BlockTpcCommunicationSpi commSpi = commSpi(srv); if (colCfg.getAtomicityMode() == ATOMIC) - commSpi.blockMessage(GridNearAtomicUpdateResponse.class); + commSpi.blockMessage(GridNearAtomicMultipleUpdateResponse.class); else commSpi.blockMessage(GridNearTxPrepareResponse.class); From c39410a2dbbab7e8886a407a5661b29ee985adce Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Mon, 8 Feb 2016 18:05:34 +0300 Subject: [PATCH 19/34] ignite-2523 : SingleUpdateResponse implementation. --- .../GridNearAtomicSingleUpdateResponse.java | 195 ++++++++---------- 1 file changed, 84 insertions(+), 111 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java index 581c33b8f58b4..0bea0dda059f0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java @@ -30,6 +30,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.GridLongList; 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; import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; import org.apache.ignite.plugin.extensions.communication.MessageReader; @@ -38,11 +39,10 @@ import java.io.Externalizable; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; public class GridNearAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridNearAtomicUpdateResponse { @@ -70,28 +70,21 @@ public class GridNearAtomicSingleUpdateResponse extends GridCacheMessage impleme @GridToStringInclude private GridCacheReturn ret; - /** Failed keys. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private volatile Collection failedKeys; + private KeyCacheObject key; - /** Keys that should be remapped. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List remapKeys; + private boolean failed; - /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearValsIdxs; + private boolean remap; - /** Indexes of keys for which update was skipped (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearSkipIdxs; + private boolean hasNearVal; - /** Values generated on primary node which should be put to originating node's near cache. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; + private CacheObject nearVal; + + private boolean nearSkip; + + private long nearTtl = -1; + + private long nearExpireTime = -1; /** Version generated on primary node to be used for originating node's near cache update. */ private GridCacheVersion nearVer; @@ -168,7 +161,10 @@ public GridNearAtomicSingleUpdateResponse(int cacheId, UUID nodeId, GridCacheVer * @return Collection of failed keys. */ @Override public Collection failedKeys() { - return failedKeys; + if (failed && key != null) + return Collections.singletonList(key); + + return Collections.emptyList(); } /** @@ -190,14 +186,23 @@ public void returnValue(GridCacheReturn ret) { * @param remapKeys Remap keys. */ @Override public void remapKeys(List remapKeys) { - this.remapKeys = remapKeys; + assert remapKeys.size() <= 1; + + if (remapKeys.isEmpty()) + return; + + key = remapKeys.get(0); + remap = true; } /** * @return Remap keys. */ @Override public Collection remapKeys() { - return remapKeys; + if (remap && key != null) + return Collections.singletonList(key); + + return Collections.emptyList(); } /** @@ -212,15 +217,13 @@ public void returnValue(GridCacheReturn ret) { @Nullable CacheObject val, long ttl, long expireTime) { - if (nearValsIdxs == null) { - nearValsIdxs = new ArrayList<>(); - nearVals = new ArrayList<>(); - } - addNearTtl(keyIdx, ttl, expireTime); + assert keyIdx == 0; - nearValsIdxs.add(keyIdx); - nearVals.add(val); + nearVal = val; + hasNearVal = true; + + addNearTtl(keyIdx, ttl, expireTime); } /** @@ -230,29 +233,11 @@ public void returnValue(GridCacheReturn ret) { */ @Override @SuppressWarnings("ForLoopReplaceableByForEach") public void addNearTtl(int keyIdx, long ttl, long expireTime) { - if (ttl >= 0) { - if (nearTtls == null) { - nearTtls = new GridLongList(16); + assert keyIdx == 0; - for (int i = 0; i < keyIdx; i++) - nearTtls.add(-1L); - } - } - - if (nearTtls != null) - nearTtls.add(ttl); + nearTtl = ttl >= 0 ? ttl : -1; - if (expireTime >= 0) { - if (nearExpireTimes == null) { - nearExpireTimes = new GridLongList(16); - - for (int i = 0; i < keyIdx; i++) - nearExpireTimes.add(-1); - } - } - - if (nearExpireTimes != null) - nearExpireTimes.add(expireTime); + nearExpireTime = expireTime >= 0 ? expireTime : -1; } /** @@ -260,11 +245,8 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @return Expire time for near cache update. */ @Override public long nearExpireTime(int idx) { - if (nearExpireTimes != null) { - assert idx >= 0 && idx < nearExpireTimes.size(); - - return nearExpireTimes.get(idx); - } + if (idx == 0) + return nearExpireTime; return -1L; } @@ -274,11 +256,8 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @return TTL for near cache update. */ @Override public long nearTtl(int idx) { - if (nearTtls != null) { - assert idx >= 0 && idx < nearTtls.size(); - - return nearTtls.get(idx); - } + if (idx == 0) + return nearTtl; return -1L; } @@ -301,26 +280,31 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @param keyIdx Index of key for which update was skipped */ @Override public void addSkippedIndex(int keyIdx) { - if (nearSkipIdxs == null) - nearSkipIdxs = new ArrayList<>(); + assert keyIdx == 0; - nearSkipIdxs.add(keyIdx); - - addNearTtl(keyIdx, -1L, -1L); + nearSkip = true; + nearTtl = -1; + nearExpireTime = -1; } /** * @return Indexes of keys for which update was skipped */ @Override @Nullable public List skippedIndexes() { - return nearSkipIdxs; + if (nearSkip && key != null) + return Collections.singletonList(0); + + return Collections.emptyList(); } /** * @return Indexes of keys for which values were generated on primary node. */ @Override @Nullable public List nearValuesIndexes() { - return nearValsIdxs; + if (hasNearVal && key != null) + return Collections.singletonList(0); + + return Collections.emptyList(); } /** @@ -328,7 +312,12 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @return Value generated on primary node which should be put to originating node's near cache. */ @Override @Nullable public CacheObject nearValue(int idx) { - return nearVals.get(idx); + assert idx == 0; + + if (hasNearVal) + return nearVal; + + return null; } /** @@ -338,13 +327,10 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @param e Error cause. */ @Override public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ConcurrentLinkedQueue<>(); - - failedKeys.add(key); + this.key = key; + failed = true; - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); + err = new IgniteCheckedException("Failed to update keys on primary node."); err.addSuppressed(e); } @@ -357,14 +343,13 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { */ @Override public synchronized void addFailedKeys(Collection keys, Throwable e) { if (keys != null) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); + assert keys.size() <= 1; - failedKeys.addAll(keys); + if (keys.size() == 1) + key = F.first(keys); } - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); + err = new IgniteCheckedException("Failed to update keys on primary node."); err.addSuppressed(e); } @@ -378,15 +363,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { */ @Override public synchronized void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); - - failedKeys.addAll(keys); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); + addFailedKeys(keys, e); } /** {@inheritDoc} @@ -399,11 +376,9 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { GridCacheContext cctx = ctx.cacheContext(cacheId); - prepareMarshalCacheObjects(failedKeys, cctx); + prepareMarshalCacheObject(key, cctx); - prepareMarshalCacheObjects(remapKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); + prepareMarshalCacheObject(nearVal, cctx); if (ret != null) ret.prepareMarshal(cctx); @@ -418,11 +393,9 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { GridCacheContext cctx = ctx.cacheContext(cacheId); - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - - finishUnmarshalCacheObjects(remapKeys, cctx, ldr); + finishUnmarshalCacheObject(key, cctx, ldr); - finishUnmarshalCacheObjects(nearVals, cctx, ldr); + finishUnmarshalCacheObject(nearVal, cctx, ldr); if (ret != null) ret.finishUnmarshal(cctx, ldr); @@ -455,7 +428,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { writer.incrementState(); case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + if (!writer.writeBoolean("failed", failed)) return false; writer.incrementState(); @@ -467,31 +440,31 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { writer.incrementState(); case 6: - if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + if (!writer.writeLong("nearExpireTime", nearExpireTime)) return false; writer.incrementState(); case 7: - if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) + if (!writer.writeBoolean("nearSkip", nearSkip)) return false; writer.incrementState(); case 8: - if (!writer.writeMessage("nearTtls", nearTtls)) + if (!writer.writeLong("nearTtl", nearTtl)) return false; writer.incrementState(); case 9: - if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + if (!writer.writeMessage("nearVal", nearVal)) return false; writer.incrementState(); case 10: - if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) + if (!writer.writeBoolean("hasNearVal", hasNearVal)) return false; writer.incrementState(); @@ -503,7 +476,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { writer.incrementState(); case 12: - if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) + if (!writer.writeMessage("key", key)) return false; writer.incrementState(); @@ -539,7 +512,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + failed = reader.readBoolean("failed"); if (!reader.isLastRead()) return false; @@ -555,7 +528,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 6: - nearExpireTimes = reader.readMessage("nearExpireTimes"); + nearExpireTime = reader.readLong("nearExpireTime"); if (!reader.isLastRead()) return false; @@ -563,7 +536,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 7: - nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); + nearSkip = reader.readBoolean("nearSkip"); if (!reader.isLastRead()) return false; @@ -571,7 +544,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 8: - nearTtls = reader.readMessage("nearTtls"); + nearTtl = reader.readLong("nearTtl"); if (!reader.isLastRead()) return false; @@ -579,7 +552,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 9: - nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + nearVal = reader.readMessage("nearVal"); if (!reader.isLastRead()) return false; @@ -587,7 +560,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 10: - nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); + hasNearVal = reader.readBoolean("hasNearVal"); if (!reader.isLastRead()) return false; @@ -603,7 +576,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { reader.incrementState(); case 12: - remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); + key = reader.readMessage("key"); if (!reader.isLastRead()) return false; From 3c8d02a00b2bcbc194fd2112d9f8cb58ab7d571a Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Mon, 8 Feb 2016 18:25:21 +0300 Subject: [PATCH 20/34] ignite-2523 : Generalized usage of GridNearAtomicUpdateRequest/Response. --- .../processors/cache/GridCacheIoManager.java | 3 ++- .../GridNearAtomicMultipleUpdateRequest.java | 6 ++--- .../GridNearAtomicSingleUpdateRequest.java | 6 ++--- .../atomic/GridNearAtomicUpdateFuture.java | 22 ++++++++++++------- .../atomic/GridNearAtomicUpdateRequest.java | 4 ++-- .../distributed/near/GridNearAtomicCache.java | 3 ++- 6 files changed, 26 insertions(+), 18 deletions(-) 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 ea972774641f2..7ba95426cacc1 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 @@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateResponse; 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.near.GridNearGetRequest; @@ -590,7 +591,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC case -23: { GridNearAtomicSingleUpdateRequest req = (GridNearAtomicSingleUpdateRequest)msg; - GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse( + GridNearAtomicSingleUpdateResponse res = new GridNearAtomicSingleUpdateResponse( ctx.cacheId(), nodeId, req.futureVersion(), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java index 6f109befb5c2b..650d350f76a84 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java @@ -157,7 +157,7 @@ public class GridNearAtomicMultipleUpdateRequest extends GridCacheMessage /** */ @GridDirectTransient - private GridNearAtomicMultipleUpdateResponse res; + private GridNearAtomicUpdateResponse res; /** Maximum possible size of inner collections. */ @GridDirectTransient @@ -502,7 +502,7 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicMultipleUpdateResponse res) { + @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { if (this.res == null) { this.res = res; @@ -513,7 +513,7 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicMultipleUpdateResponse response() { + @Override @Nullable public GridNearAtomicUpdateResponse response() { return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 87140100bdd79..1e981afd9a212 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -149,7 +149,7 @@ public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage /** */ @GridDirectTransient - private GridNearAtomicMultipleUpdateResponse res; + private GridNearAtomicUpdateResponse res; /** * Empty constructor required by {@link Externalizable}. @@ -427,7 +427,7 @@ else if (val != null) { } /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicMultipleUpdateResponse res) { + @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { if (this.res == null) { this.res = res; @@ -438,7 +438,7 @@ else if (val != null) { } /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicMultipleUpdateResponse response() { + @Override @Nullable public GridNearAtomicUpdateResponse response() { return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 68ee67bb23120..682935f4f00c7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -349,7 +349,7 @@ public void onResult(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { * @param req Update request. * @param res Update response. */ - private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { + private void updateNear(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { assert nearEnabled; if (res.remapKeys() != null || !req.hasPrimary()) @@ -570,7 +570,7 @@ private class UpdateState { * @param nodeId Left node ID. */ void onNodeLeft(UUID nodeId) { - GridNearAtomicMultipleUpdateResponse res = null; + GridNearAtomicUpdateResponse res = null; synchronized (this) { GridNearAtomicUpdateRequest req; @@ -581,10 +581,16 @@ void onNodeLeft(UUID nodeId) { req = mappings != null ? mappings.get(nodeId) : null; if (req != null && req.response() == null) { - res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); + if (req instanceof GridNearAtomicSingleUpdateRequest) + res = new GridNearAtomicSingleUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); + else + res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + "before response is received: " + nodeId); @@ -605,7 +611,7 @@ void onNodeLeft(UUID nodeId) { * @param nodeErr {@code True} if response was created on node failure. */ @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) - void onResult(UUID nodeId, GridNearAtomicMultipleUpdateResponse res, boolean nodeErr) { + void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { GridNearAtomicUpdateRequest req; AffinityTopologyVersion remapTopVer = null; @@ -737,7 +743,7 @@ else if (res.error() != null) { if (rcvAll && nearEnabled) { if (mappings != null) { for (GridNearAtomicMultipleUpdateRequest req0 : mappings.values()) { - GridNearAtomicMultipleUpdateResponse res0 = req0.response(); + GridNearAtomicUpdateResponse res0 = req0.response(); assert res0 != null : req0; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index c1977bfd2d92e..960add7eb0ba3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -190,10 +190,10 @@ public interface GridNearAtomicUpdateRequest { * @param res Response. * @return {@code True} if current response was {@code null}. */ - public boolean onResponse(GridNearAtomicMultipleUpdateResponse res); + public boolean onResponse(GridNearAtomicUpdateResponse res); /** * @return Response. */ - @Nullable public GridNearAtomicMultipleUpdateResponse response(); + @Nullable public GridNearAtomicUpdateResponse response(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 2546691d7bfcc..5aef8e76b7915 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -128,7 +129,7 @@ public void dht(GridDhtAtomicCache dht) { */ public void processNearAtomicUpdateResponse( GridNearAtomicUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res + GridNearAtomicUpdateResponse res ) { if (F.size(res.failedKeys()) == req.keys().size()) return; From cb5bdb3f19cefe14380ac169d49e6e86bde1899a Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Mon, 8 Feb 2016 18:51:55 +0300 Subject: [PATCH 21/34] ignite-2523 : Generalized usage of GridNearAtomicUpdateRequest/Response. --- .../dht/atomic/GridDhtAtomicCache.java | 45 +++++++++++-------- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 8 ++-- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index b0504db488823..05205e31988a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -55,6 +55,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheMapEntry; import org.apache.ignite.internal.processors.cache.GridCacheMapEntryFactory; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult; @@ -139,7 +140,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { Integer.getInteger(IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT, 500); /** Update reply closure. */ - private CI2 updateReplyClos; + private CI2 updateReplyClos; /** Pending */ private ConcurrentMap pendingResponses = new ConcurrentHashMap8<>(); @@ -192,9 +193,9 @@ public GridDhtAtomicCache(GridCacheContext ctx, GridCacheConcurrentMap map } }); - updateReplyClos = new CI2() { + updateReplyClos = new CI2() { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { if (ctx.config().getAtomicWriteOrderMode() == CLOCK) { assert req.writeSynchronizationMode() != FULL_ASYNC : req; @@ -1311,7 +1312,7 @@ else if (!skipVals && ctx.config().isStatisticsEnabled()) public void updateAllAsyncInternal( final UUID nodeId, final GridNearAtomicUpdateRequest req, - final CI2 completionCb + final CI2 completionCb ) { IgniteInternalFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); @@ -1336,10 +1337,16 @@ public void updateAllAsyncInternal( public void updateAllAsyncInternal0( UUID nodeId, GridNearAtomicUpdateRequest req, - CI2 completionCb + CI2 completionCb ) { - GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), - ctx.deploymentEnabled()); + GridNearAtomicUpdateResponse res; + + if (req instanceof GridNearAtomicSingleUpdateRequest) + res = new GridNearAtomicSingleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), + ctx.deploymentEnabled()); + else + res = new GridNearAtomicMultipleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), + ctx.deploymentEnabled()); List keys = req.keys(); @@ -1424,7 +1431,7 @@ public void updateAllAsyncInternal0( UpdateBatchResult updRes = updateWithBatch(node, hasNear, req, - res, + (GridNearAtomicMultipleUpdateResponse) res, locked, ver, dhtFut, @@ -1563,7 +1570,7 @@ private UpdateBatchResult updateWithBatch( List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -1797,7 +1804,7 @@ else if (op == UPDATE) { if (intercept) { CacheObject old = entry.innerGet( - null, + null, /*read swap*/true, /*read through*/ctx.loadPreviousValue(), /*fail fast*/false, @@ -1812,7 +1819,7 @@ else if (op == UPDATE) { req.keepBinary()); Object val = ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(), - old, req.keepBinary()), + old, req.keepBinary()), updated.value(ctx.cacheObjectContext(), false)); if (val == null) @@ -1975,11 +1982,11 @@ private UpdateSingleResult updateSingle( ClusterNode node, boolean hasNear, GridNearAtomicUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res, + GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, @@ -2214,7 +2221,7 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable Collection rmvKeys, @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, - CI2 completionCb, + CI2 completionCb, final GridNearAtomicUpdateRequest req, final GridNearAtomicMultipleUpdateResponse res, boolean replicate, @@ -2688,8 +2695,8 @@ else if (req.operation() == UPDATE) { @Nullable private GridDhtAtomicUpdateFuture createDhtFuture( GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, - GridNearAtomicMultipleUpdateResponse updateRes, - CI2 completionCb, + GridNearAtomicUpdateResponse updateRes, + CI2 completionCb, boolean force ) { if (!force) { @@ -2944,9 +2951,9 @@ private void processDhtAtomicDeferredUpdateResponse(UUID nodeId, GridDhtAtomicDe * @param nodeId Originating node ID. * @param res Near update response. */ - private void sendNearUpdateReply(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { + private void sendNearUpdateReply(UUID nodeId, GridNearAtomicUpdateResponse res) { try { - ctx.io().send(nodeId, res, ctx.ioPolicy()); + ctx.io().send(nodeId, (GridCacheMessage) res, ctx.ioPolicy()); } catch (ClusterTopologyCheckedException ignored) { U.warn(log, "Failed to send near update reply to node because it left grid: " + @@ -3188,7 +3195,7 @@ public boolean addResponse(GridCacheVersion ver) { respVers.add(ver); - if (respVers.sizex() > DEFERRED_UPDATE_RESPONSE_BUFFER_SIZE && guard.compareAndSet(false, true)) + if (respVers.sizex() > DEFERRED_UPDATE_RESPONSE_BUFFER_SIZE && guard.compareAndSet(false, true)) snd = true; } finally { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 68c639d9a7dfb..3a31700dcedfc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -77,7 +77,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement /** Completion callback. */ @GridToStringExclude - private final CI2 completionCb; + private final CI2 completionCb; /** Mappings. */ @GridToStringInclude @@ -90,7 +90,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement private final GridNearAtomicUpdateRequest updateReq; /** Update response. */ - private final GridNearAtomicMultipleUpdateResponse updateRes; + private final GridNearAtomicUpdateResponse updateRes; /** Future keys. */ private final Collection keys; @@ -110,10 +110,10 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, - GridNearAtomicMultipleUpdateResponse updateRes + GridNearAtomicUpdateResponse updateRes ) { this.cctx = cctx; this.writeVer = writeVer; From 4f8220e6da06443f1ef42ac3f4b4e46f5100dcd1 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 14:38:12 +0300 Subject: [PATCH 22/34] ignite-2523 : finished generalization of GridNearAtomicUpdate. --- .../atomic/GridNearAtomicUpdateFuture.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 682935f4f00c7..55442dc2d520c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -71,7 +71,7 @@ /** * DHT atomic cache near update future. */ -public class GridNearAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture{ +public class GridNearAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture { /** Version where single-put optimization appeared.*/ public static final IgniteProductVersion SINGLE_PUT_MSG_SINCE = IgniteProductVersion.fromString("1.6.0"); @@ -511,7 +511,8 @@ private void doUpdate(Map mappings) { if (locUpdate != null) { cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, new CI2() { - @Override public void apply(GridNearAtomicMultipleUpdateRequest req, GridNearAtomicMultipleUpdateResponse res) { + @Override public void apply(GridNearAtomicMultipleUpdateRequest req, + GridNearAtomicMultipleUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -610,8 +611,8 @@ void onNodeLeft(UUID nodeId) { * @param res Response. * @param nodeErr {@code True} if response was created on node failure. */ - @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) - void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { + @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) void onResult(UUID nodeId, + GridNearAtomicUpdateResponse res, boolean nodeErr) { GridNearAtomicUpdateRequest req; AffinityTopologyVersion remapTopVer = null; @@ -818,10 +819,18 @@ else if (!nodeErr) */ void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { synchronized (this) { - GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); + GridNearAtomicUpdateResponse res; + + if (req instanceof GridNearAtomicSingleUpdateRequest) + res = new GridNearAtomicSingleUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); + else + res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); res.addFailedKeys(req.keys(), e); @@ -1043,7 +1052,7 @@ else if (conflictPutVals != null) { val = conflictPutVal.valueEx(); conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); + conflictTtl = conflictPutVal.ttl(); conflictExpireTime = conflictPutVal.expireTime(); } else if (conflictRmvVals != null) { @@ -1298,7 +1307,7 @@ private void addFailedKeys(Collection failedKeys, } /** {@inheritDoc} */ - @Override public synchronized String toString() { + @Override public synchronized String toString() { return S.toString(UpdateState.class, this); } } From 2f6aff8024794cd980fd77bb96e9a74876fb7442 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 15:04:52 +0300 Subject: [PATCH 23/34] ignite-2523 : Fixed failing tests. --- .../dht/atomic/GridDhtAtomicCache.java | 15 +++++++++++---- .../atomic/GridNearAtomicSingleUpdateRequest.java | 2 ++ .../GridNearAtomicSingleUpdateResponse.java | 8 ++++---- .../dht/atomic/GridNearAtomicUpdateFuture.java | 6 +++--- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 05205e31988a8..629aa2502c120 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -269,6 +269,12 @@ else if (res.error() != null) { } }); + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicSingleUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicSingleUpdateResponse res) { + processNearAtomicUpdateResponse(nodeId, res); + } + }); + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicUpdateRequest.class, new CI2() { @Override public void apply(UUID nodeId, GridDhtAtomicUpdateRequest req) { processDhtAtomicUpdateRequest(nodeId, req); @@ -868,7 +874,8 @@ protected IgniteInternalFuture asyncOp(final CO> TRANSFORM); return resFut.chain(new CX1>>, Map>>() { - @Override public Map> applyx(IgniteInternalFuture>> fut) throws IgniteCheckedException { + @Override public Map> applyx( + IgniteInternalFuture>> fut) throws IgniteCheckedException { Map resMap = (Map)fut.get(); return ctx.unwrapInvokeResult(resMap, keepBinary); @@ -1431,7 +1438,7 @@ public void updateAllAsyncInternal0( UpdateBatchResult updRes = updateWithBatch(node, hasNear, req, - (GridNearAtomicMultipleUpdateResponse) res, + (GridNearAtomicMultipleUpdateResponse)res, locked, ver, dhtFut, @@ -2741,7 +2748,7 @@ private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateReq * @param res Near atomic update response. */ @SuppressWarnings("unchecked") - private void processNearAtomicUpdateResponse(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { + private void processNearAtomicUpdateResponse(UUID nodeId, GridNearAtomicUpdateResponse res) { if (log.isDebugEnabled()) log.debug("Processing near atomic update response [nodeId=" + nodeId + ", res=" + res + ']'); @@ -2953,7 +2960,7 @@ private void processDhtAtomicDeferredUpdateResponse(UUID nodeId, GridDhtAtomicDe */ private void sendNearUpdateReply(UUID nodeId, GridNearAtomicUpdateResponse res) { try { - ctx.io().send(nodeId, (GridCacheMessage) res, ctx.ioPolicy()); + ctx.io().send(nodeId, (GridCacheMessage)res, ctx.ioPolicy()); } catch (ClusterTopologyCheckedException ignored) { U.warn(log, "Failed to send near update reply to node because it left grid: " + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 1e981afd9a212..e69be07a1143b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -213,6 +213,8 @@ public GridNearAtomicSingleUpdateRequest( boolean clientReq, boolean addDepInfo ) { + System.out.println("???"); + assert futVer != null; this.key = key; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java index 0bea0dda059f0..65dc08e1da75a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java @@ -164,7 +164,7 @@ public GridNearAtomicSingleUpdateResponse(int cacheId, UUID nodeId, GridCacheVer if (failed && key != null) return Collections.singletonList(key); - return Collections.emptyList(); + return null; } /** @@ -202,7 +202,7 @@ public void returnValue(GridCacheReturn ret) { if (remap && key != null) return Collections.singletonList(key); - return Collections.emptyList(); + return null; } /** @@ -294,7 +294,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { if (nearSkip && key != null) return Collections.singletonList(0); - return Collections.emptyList(); + return null; } /** @@ -304,7 +304,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { if (hasNearVal && key != null) return Collections.singletonList(0); - return Collections.emptyList(); + return null; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 55442dc2d520c..8edd0d476e05d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -339,7 +339,7 @@ public void map() { * @param nodeId Node ID. * @param res Update response. */ - public void onResult(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { + public void onResult(UUID nodeId, GridNearAtomicUpdateResponse res) { state.onResult(nodeId, res, false); } @@ -454,9 +454,9 @@ private Collection mapKey( private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, - new CI2() { + new CI2() { @Override public void apply(GridNearAtomicUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res) { + GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); From 6040f45eae844fd40c113de452e70078dae9a95c Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 16:14:57 +0300 Subject: [PATCH 24/34] ignite-2523 : Fixed test failures. --- .../dht/atomic/GridNearAtomicSingleUpdateRequest.java | 2 -- .../dht/atomic/GridNearAtomicSingleUpdateResponse.java | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index e69be07a1143b..1e981afd9a212 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -213,8 +213,6 @@ public GridNearAtomicSingleUpdateRequest( boolean clientReq, boolean addDepInfo ) { - System.out.println("???"); - assert futVer != null; this.key = key; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java index 65dc08e1da75a..b3f7e74fefd4b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java @@ -291,7 +291,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @return Indexes of keys for which update was skipped */ @Override @Nullable public List skippedIndexes() { - if (nearSkip && key != null) + if (nearSkip) return Collections.singletonList(0); return null; @@ -301,7 +301,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { * @return Indexes of keys for which values were generated on primary node. */ @Override @Nullable public List nearValuesIndexes() { - if (hasNearVal && key != null) + if (hasNearVal) return Collections.singletonList(0); return null; From 3391c847e9825405d8ca2f7df7e01ba432f60b1b Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 17:43:39 +0300 Subject: [PATCH 25/34] ignite-2523 : Created GridDhtAtomicSingleUpdateRequest optimized implementation. --- .../communication/GridIoMessageFactory.java | 20 +- .../processors/cache/GridCacheIoManager.java | 22 +- .../dht/atomic/GridDhtAtomicCache.java | 32 +- .../GridDhtAtomicMultipleUpdateRequest.java | 1065 +++++++++++++++++ .../GridDhtAtomicMultipleUpdateResponse.java | 297 +++++ .../GridDhtAtomicSingleUpdateRequest.java | 1035 ++++++++++++++++ .../GridDhtAtomicSingleUpdateResponse.java | 296 +++++ .../dht/atomic/GridDhtAtomicUpdateFuture.java | 88 +- .../atomic/GridDhtAtomicUpdateRequest.java | 1056 +--------------- .../atomic/GridDhtAtomicUpdateResponse.java | 300 +---- .../GridNearAtomicSingleUpdateResponse.java | 2 +- .../distributed/near/GridNearAtomicCache.java | 2 +- .../GridCacheAtomicMessageCountSelfTest.java | 6 +- ...tomicInvalidPartitionHandlingSelfTest.java | 2 +- 14 files changed, 2911 insertions(+), 1312 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.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 4d769afd17d33..23661047c911f 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 @@ -66,8 +66,10 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtUnlockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicDeferredUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; @@ -354,12 +356,12 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 38: - msg = new GridDhtAtomicUpdateRequest(); + msg = new GridDhtAtomicMultipleUpdateRequest(); break; case 39: - msg = new GridDhtAtomicUpdateResponse(); + msg = new GridDhtAtomicMultipleUpdateResponse(); break; @@ -738,6 +740,16 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; + case -25: + msg = new GridDhtAtomicSingleUpdateRequest(); + + break; + + case -26: + msg = new GridDhtAtomicSingleUpdateResponse(); + + break; + // [-3..119] [124] - this // [120..123] - DR // [-4..-22] - SQL 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 7ba95426cacc1..a4ad5004b350c 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 @@ -42,6 +42,10 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; @@ -398,14 +402,22 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC case 38: { GridDhtAtomicUpdateRequest req = (GridDhtAtomicUpdateRequest)msg; - GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse( - ctx.cacheId(), - req.futureVersion(), - ctx.deploymentEnabled()); + GridDhtAtomicUpdateResponse res; + + if (req instanceof GridDhtAtomicSingleUpdateRequest) + res = new GridDhtAtomicSingleUpdateResponse( + ctx.cacheId(), + req.futureVersion(), + ctx.deploymentEnabled()); + else + res = new GridDhtAtomicMultipleUpdateResponse( + ctx.cacheId(), + req.futureVersion(), + ctx.deploymentEnabled()); res.onError(req.classError()); - sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy()); + sendResponseOnFailedMessage(nodeId, (GridCacheMessage) res, cctx, ctx.ioPolicy()); } break; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 629aa2502c120..454a3aacee87e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -275,14 +275,26 @@ else if (res.error() != null) { } }); - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicUpdateRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicMultipleUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicMultipleUpdateRequest req) { processDhtAtomicUpdateRequest(nodeId, req); } }); - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicUpdateResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicSingleUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicSingleUpdateRequest req) { + processDhtAtomicUpdateRequest(nodeId, req); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicMultipleUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicMultipleUpdateResponse res) { + processDhtAtomicUpdateResponse(nodeId, res); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicSingleUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicSingleUpdateResponse res) { processDhtAtomicUpdateResponse(nodeId, res); } }); @@ -2774,8 +2786,14 @@ private void processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicUpdateReque GridCacheVersion ver = req.writeVersion(); // Always send update reply. - GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.futureVersion(), - ctx.deploymentEnabled()); + GridDhtAtomicUpdateResponse res; + + if (req instanceof GridDhtAtomicSingleUpdateRequest) + res = new GridDhtAtomicSingleUpdateResponse(ctx.cacheId(), req.futureVersion(), + ctx.deploymentEnabled()); + else + res = new GridDhtAtomicMultipleUpdateResponse(ctx.cacheId(), req.futureVersion(), + ctx.deploymentEnabled()); Boolean replicate = ctx.isDrEnabled(); @@ -2871,7 +2889,7 @@ private void processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicUpdateReque try { if (res.failedKeys() != null || res.nearEvicted() != null || req.writeSynchronizationMode() == FULL_SYNC) - ctx.io().send(nodeId, res, ctx.ioPolicy()); + ctx.io().send(nodeId, (GridCacheMessage) res, ctx.ioPolicy()); else { // No failed keys and sync mode is not FULL_SYNC, thus sending deferred response. sendDeferredUpdateResponse(nodeId, req.futureVersion()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java new file mode 100644 index 0000000000000..40d68faaa04ab --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java @@ -0,0 +1,1065 @@ +/* + * 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.atomic; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import javax.cache.processor.EntryProcessor; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Lite dht cache backup update request. + */ +public class GridDhtAtomicMultipleUpdateRequest extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateRequest { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID. */ + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Write version. */ + private GridCacheVersion writeVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Previous values. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List prevVals; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** TTLs. */ + private GridLongList ttls; + + /** Conflict expire time. */ + private GridLongList conflictExpireTimes; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Near cache keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearKeys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Force transform backups flag. */ + private boolean forceTransformBackups; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Near entry processors. */ + @GridDirectTransient + private List> nearEntryProcessors; + + /** Near entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List nearEntryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Partition. */ + private GridLongList updateCntrs; + + /** On response flag. Access should be synced on future. */ + @GridDirectTransient + private boolean onRes; + + /** */ + @GridDirectTransient + private List partIds; + + /** */ + @GridDirectTransient + private List locPrevVals; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicMultipleUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param writeVer Write version for cache values. + * @param invokeArgs Optional arguments for entry processor. + * @param syncMode Cache write synchronization mode. + * @param topVer Topology version. + * @param forceTransformBackups Force transform backups flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicMultipleUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + GridCacheVersion writeVer, + CacheWriteSynchronizationMode syncMode, + @NotNull AffinityTopologyVersion topVer, + boolean forceTransformBackups, + UUID subjId, + int taskNameHash, + Object[] invokeArgs, + boolean addDepInfo, + boolean keepBinary + ) { + assert invokeArgs == null || forceTransformBackups; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.writeVer = writeVer; + this.syncMode = syncMode; + this.topVer = topVer; + this.forceTransformBackups = forceTransformBackups; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.invokeArgs = invokeArgs; + this.addDepInfo = addDepInfo; + this.keepBinary = keepBinary; + + keys = new ArrayList<>(); + partIds = new ArrayList<>(); + locPrevVals = new ArrayList<>(); + + if (forceTransformBackups) { + entryProcessors = new ArrayList<>(); + entryProcessorsBytes = new ArrayList<>(); + } + else + vals = new ArrayList<>(); + } + + /** + * @return Force transform backups flag. + */ + @Override public boolean forceTransformBackups() { + return forceTransformBackups; + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param addPrevVal If {@code true} adds previous value. + * @param prevVal Previous value. + */ + @Override public void addWriteValue(KeyCacheObject key, + @Nullable CacheObject val, + EntryProcessor entryProcessor, + long ttl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, + boolean addPrevVal, + int partId, + @Nullable CacheObject prevVal, + @Nullable Long updateIdx) { + keys.add(key); + + partIds.add(partId); + + locPrevVals.add(prevVal); + + if (forceTransformBackups) { + assert entryProcessor != null; + + entryProcessors.add(entryProcessor); + } + else + vals.add(val); + + if (addPrevVal) { + if (prevVals == null) + prevVals = new ArrayList<>(); + + prevVals.add(prevVal); + } + + if (updateIdx != null) { + if (updateCntrs == null) + updateCntrs = new GridLongList(); + + updateCntrs.add(updateIdx); + } + + // In case there is no conflict, do not create the list. + if (conflictVer != null) { + if (conflictVers == null) { + conflictVers = new ArrayList<>(); + + for (int i = 0; i < keys.size() - 1; i++) + conflictVers.add(null); + } + + conflictVers.add(conflictVer); + } + else if (conflictVers != null) + conflictVers.add(null); + + if (ttl >= 0) { + if (ttls == null) { + ttls = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + ttls.add(CU.TTL_NOT_CHANGED); + } + } + + if (ttls != null) + ttls.add(ttl); + + if (conflictExpireTime >= 0) { + if (conflictExpireTimes == null) { + conflictExpireTimes = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + } + + if (conflictExpireTimes != null) + conflictExpireTimes.add(conflictExpireTime); + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL. + * @param expireTime Expire time. + */ + @Override public void addNearWriteValue(KeyCacheObject key, + @Nullable CacheObject val, + EntryProcessor entryProcessor, + long ttl, + long expireTime) { + if (nearKeys == null) { + nearKeys = new ArrayList<>(); + + if (forceTransformBackups) { + nearEntryProcessors = new ArrayList<>(); + nearEntryProcessorsBytes = new ArrayList<>(); + } + else + nearVals = new ArrayList<>(); + } + + nearKeys.add(key); + + if (forceTransformBackups) { + assert entryProcessor != null; + + nearEntryProcessors.add(entryProcessor); + } + else + nearVals.add(val); + + if (ttl >= 0) { + if (nearTtls == null) { + nearTtls = new GridLongList(nearKeys.size()); + + for (int i = 0; i < nearKeys.size() - 1; i++) + nearTtls.add(CU.TTL_NOT_CHANGED); + } + } + + if (nearTtls != null) + nearTtls.add(ttl); + + if (expireTime >= 0) { + if (nearExpireTimes == null) { + nearExpireTimes = new GridLongList(nearKeys.size()); + + for (int i = 0; i < nearKeys.size() - 1; i++) + nearExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + } + + if (nearExpireTimes != null) + nearExpireTimes.add(expireTime); + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID. + */ + @Override public UUID nodeId() { + return nodeId; + } + + /** + * @return Subject ID. + */ + @Override public UUID subjectId() { + return subjId; + } + + /** + * @return Task name. + */ + @Override public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Keys size. + */ + @Override public int size() { + return keys.size(); + } + + /** + * @return Keys size. + */ + @Override public int nearSize() { + return nearKeys != null ? nearKeys.size() : 0; + } + + /** + * @return Version assigned on primary node. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @return Write version. + */ + @Override public GridCacheVersion writeVersion() { + return writeVer; + } + + /** + * @return Cache write synchronization mode. + */ + @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Keys. + */ + @Override public Collection keys() { + return keys; + } + + /** + * @param idx Key index. + * @return Key. + */ + @Override public KeyCacheObject key(int idx) { + return keys.get(idx); + } + + /** + * @param idx Partition index. + * @return Partition id. + */ + @Override public int partitionId(int idx) { + return partIds.get(idx); + } + + /** + * @param updCntr Update counter. + * @return Update counter. + */ + @Override public Long updateCounter(int updCntr) { + if (updateCntrs != null && updCntr < updateCntrs.size()) + return updateCntrs.get(updCntr); + + return null; + } + + /** + * @param idx Near key index. + * @return Key. + */ + @Override public KeyCacheObject nearKey(int idx) { + return nearKeys.get(idx); + } + + /** + * @return Keep binary flag. + */ + @Override public boolean keepBinary() { + return keepBinary; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject value(int idx) { + if (vals != null) + return vals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject previousValue(int idx) { + if (prevVals != null) + return prevVals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject localPreviousValue(int idx) { + return locPrevVals.get(idx); + } + + /** + * @param idx Key index. + * @return Entry processor. + */ + @Override @Nullable public EntryProcessor entryProcessor(int idx) { + return entryProcessors == null ? null : entryProcessors.get(idx); + } + + /** + * @param idx Near key index. + * @return Value. + */ + @Override @Nullable public CacheObject nearValue(int idx) { + if (nearVals != null) + return nearVals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Transform closure. + */ + @Override @Nullable public EntryProcessor nearEntryProcessor(int idx) { + return nearEntryProcessors == null ? null : nearEntryProcessors.get(idx); + } + + /** + * @param idx Index. + * @return Conflict version. + */ + @Override @Nullable public GridCacheVersion conflictVersion(int idx) { + if (conflictVers != null) { + assert idx >= 0 && idx < conflictVers.size(); + + return conflictVers.get(idx); + } + + return null; + } + + /** + * @param idx Index. + * @return TTL. + */ + @Override public long ttl(int idx) { + if (ttls != null) { + assert idx >= 0 && idx < ttls.size(); + + return ttls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + @Override public long nearTtl(int idx) { + if (nearTtls != null) { + assert idx >= 0 && idx < nearTtls.size(); + + return nearTtls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** + * @param idx Index. + * @return Conflict expire time. + */ + @Override public long conflictExpireTime(int idx) { + if (conflictExpireTimes != null) { + assert idx >= 0 && idx < conflictExpireTimes.size(); + + return conflictExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + @Override public long nearExpireTime(int idx) { + if (nearExpireTimes != null) { + assert idx >= 0 && idx < nearExpireTimes.size(); + + return nearExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** + * @return {@code True} if on response flag changed. + */ + @Override public boolean onResponse() { + return !onRes && (onRes = true); + } + + /** + * @return Optional arguments for entry processor. + */ + @Override @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(keys, cctx); + + prepareMarshalCacheObjects(vals, cctx); + + prepareMarshalCacheObjects(nearKeys, cctx); + + prepareMarshalCacheObjects(nearVals, cctx); + + prepareMarshalCacheObjects(prevVals, cctx); + + if (forceTransformBackups) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + + if (entryProcessorsBytes == null) + entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + + if (nearEntryProcessorsBytes == null) + nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx); + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(keys, cctx, ldr); + + finishUnmarshalCacheObjects(vals, cctx, ldr); + + finishUnmarshalCacheObjects(nearKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearVals, cctx, ldr); + + finishUnmarshalCacheObjects(prevVals, cctx, ldr); + + if (forceTransformBackups) { + if (entryProcessors == null) + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + + if (nearEntryProcessors == null) + nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); + } + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeMessage("conflictExpireTimes", conflictExpireTimes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeCollection("nearEntryProcessorsBytes", nearEntryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeCollection("nearKeys", nearKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeMessage("nearTtls", nearTtls)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeCollection("prevVals", prevVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeMessage("ttls", ttls)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeMessage("updateCntrs", updateCntrs)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("writeVer", writeVer)) + 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: + conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + forceTransformBackups = reader.readBoolean("forceTransformBackups"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + keys = reader.readCollection("keys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + nearEntryProcessorsBytes = reader.readCollection("nearEntryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + nearExpireTimes = reader.readMessage("nearExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + nearKeys = reader.readCollection("nearKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + nearTtls = reader.readMessage("nearTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + prevVals = reader.readCollection("prevVals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 17: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + byte syncModeOrd; + + syncModeOrd = reader.readByte("syncMode"); + + if (!reader.isLastRead()) + return false; + + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + + reader.incrementState(); + + case 19: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + ttls = reader.readMessage("ttls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + updateCntrs = reader.readMessage("updateCntrs"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + writeVer = reader.readMessage("writeVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridDhtAtomicMultipleUpdateRequest.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 38; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 25; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicMultipleUpdateRequest.class, this, "super", super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java new file mode 100644 index 0000000000000..cd0b9a6df92cf --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java @@ -0,0 +1,297 @@ +/* + * 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.atomic; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +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.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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; +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; + +/** + * DHT atomic cache backup update response. + */ +public class GridDhtAtomicMultipleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Future version. */ + private GridCacheVersion futVer; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List failedKeys; + + /** Update error. */ + @GridDirectTransient + private IgniteCheckedException err; + + /** Serialized update error. */ + private byte[] errBytes; + + /** Evicted readers. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearEvicted; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicMultipleUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param futVer Future version. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicMultipleUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { + this.cacheId = cacheId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Future version. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + @Override public void onError(IgniteCheckedException err) { + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Failed keys. + */ + @Override public Collection failedKeys() { + return failedKeys; + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + @Override public void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ArrayList<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * @return Evicted readers. + */ + @Override public Collection nearEvicted() { + return nearEvicted; + } + + /** + * Adds near evicted key.. + * + * @param key Evicted key. + */ + @Override public void addNearEvicted(KeyCacheObject key) { + if (nearEvicted == null) + nearEvicted = new ArrayList<>(); + + nearEvicted.add(key); + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(failedKeys, cctx); + + prepareMarshalCacheObjects(nearEvicted, cctx); + + if (errBytes == null) + errBytes = ctx.marshaller().marshal(err); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridDhtAtomicMultipleUpdateResponse.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 39; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 7; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicMultipleUpdateResponse.class, this); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java new file mode 100644 index 0000000000000..c842270f07fc4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java @@ -0,0 +1,1035 @@ +/* + * + * * 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.atomic; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import javax.cache.processor.EntryProcessor; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +public class GridDhtAtomicSingleUpdateRequest extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateRequest { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID. */ + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Write version. */ + private GridCacheVersion writeVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + @GridToStringInclude + private KeyCacheObject key; + + @GridToStringInclude + private CacheObject val; + + @GridToStringInclude + private CacheObject prevVal; + + @GridToStringInclude + private GridCacheVersion conflictVer; + + private long ttl = CU.TTL_NOT_CHANGED; + + private long conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; + + private long nearTtl = CU.TTL_NOT_CHANGED; + + private long nearExpireTime = CU.EXPIRE_TIME_CALCULATE; + + @GridToStringInclude + private KeyCacheObject nearKey; + + @GridToStringInclude + private CacheObject nearVal; + + @GridDirectTransient + private EntryProcessor entryProcessor; + + private byte[] entryProcessorBytes; + + @GridDirectTransient + private EntryProcessor nearEntryProcessor; + + private byte[] nearEntryProcessorBytes; + + private long updateCntr = -1; + + @GridDirectTransient + private int partId; + + @GridDirectTransient + private CacheObject locPrevVal; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Previous values. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List prevVals; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** TTLs. */ + private GridLongList ttls; + + /** Conflict expire time. */ + private GridLongList conflictExpireTimes; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Near cache keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearKeys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Force transform backups flag. */ + private boolean forceTransformBackups; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Near entry processors. */ + @GridDirectTransient + private List> nearEntryProcessors; + + /** Near entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List nearEntryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Partition. */ + private GridLongList updateCntrs; + + /** On response flag. Access should be synced on future. */ + @GridDirectTransient + private boolean onRes; + + /** */ + @GridDirectTransient + private List partIds; + + /** */ + @GridDirectTransient + private List locPrevVals; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicSingleUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param writeVer Write version for cache values. + * @param invokeArgs Optional arguments for entry processor. + * @param syncMode Cache write synchronization mode. + * @param topVer Topology version. + * @param forceTransformBackups Force transform backups flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicSingleUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + GridCacheVersion writeVer, + CacheWriteSynchronizationMode syncMode, + @NotNull AffinityTopologyVersion topVer, + boolean forceTransformBackups, + UUID subjId, + int taskNameHash, + Object[] invokeArgs, + boolean addDepInfo, + boolean keepBinary + ) { + assert invokeArgs == null || forceTransformBackups; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.writeVer = writeVer; + this.syncMode = syncMode; + this.topVer = topVer; + this.forceTransformBackups = forceTransformBackups; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.invokeArgs = invokeArgs; + this.addDepInfo = addDepInfo; + this.keepBinary = keepBinary; + + keys = new ArrayList<>(); + partIds = new ArrayList<>(); + locPrevVals = new ArrayList<>(); + + if (forceTransformBackups) { + entryProcessors = new ArrayList<>(); + entryProcessorsBytes = new ArrayList<>(); + } + else + vals = new ArrayList<>(); + } + + /** + * @return Force transform backups flag. + */ + @Override public boolean forceTransformBackups() { + return forceTransformBackups; + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param addPrevVal If {@code true} adds previous value. + * @param prevVal Previous value. + */ + @Override public void addWriteValue(KeyCacheObject key, + @Nullable CacheObject val, + EntryProcessor entryProcessor, + long ttl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, + boolean addPrevVal, + int partId, + @Nullable CacheObject prevVal, + @Nullable Long updateIdx) { + this.key = key; + + this.partId = partId; + + this.locPrevVal = prevVal; + + if (forceTransformBackups) { + assert entryProcessor != null; + + this.entryProcessor = entryProcessor; + } + else + this.val = val; + + if (addPrevVal) + this.prevVal = prevVal; + + if (updateIdx != null) + updateCntr = updateIdx; + + this.conflictVer = conflictVer; + + if (ttl >= 0) + this.ttl = ttl; + + if (conflictExpireTime >= 0) + this.conflictExpireTime = conflictExpireTime; + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL. + * @param expireTime Expire time. + */ + @Override public void addNearWriteValue(KeyCacheObject key, + @Nullable CacheObject val, + EntryProcessor entryProcessor, + long ttl, + long expireTime) { + + nearKey = key; + + if (forceTransformBackups) { + assert entryProcessor != null; + + nearEntryProcessor = entryProcessor; + } + else + nearVal = val; + + if (ttl >= 0) + nearTtl = ttl; + + if (expireTime >= 0) + nearExpireTime = expireTime; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID. + */ + @Override public UUID nodeId() { + return nodeId; + } + + /** + * @return Subject ID. + */ + @Override public UUID subjectId() { + return subjId; + } + + /** + * @return Task name. + */ + @Override public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Keys size. + */ + @Override public int size() { + return key != null ? 1 : 0; + } + + /** + * @return Keys size. + */ + @Override public int nearSize() { + return nearKey != null ? 1 : 0; + } + + /** + * @return Version assigned on primary node. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @return Write version. + */ + @Override public GridCacheVersion writeVersion() { + return writeVer; + } + + /** + * @return Cache write synchronization mode. + */ + @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Keys. + */ + @Override public Collection keys() { + return Collections.singletonList(key); + } + + /** + * @param idx Key index. + * @return Key. + */ + @Override public KeyCacheObject key(int idx) { + assert idx == 0; + + return key; + } + + /** + * @param idx Partition index. + * @return Partition id. + */ + @Override public int partitionId(int idx) { + assert idx == 0; + + return partId; + } + + /** + * @param updCntr Update counter. + * @return Update counter. + */ + @Override public Long updateCounter(int updCntr) { + if (updCntr != 0) + return null; + + if (updateCntr == -1) + return null; + + return updateCntr; + } + + /** + * @param idx Near key index. + * @return Key. + */ + @Override public KeyCacheObject nearKey(int idx) { + assert idx == 0; + + return nearKey; + } + + /** + * @return Keep binary flag. + */ + @Override public boolean keepBinary() { + return keepBinary; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject value(int idx) { + assert idx == 0; + + return val; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject previousValue(int idx) { + assert idx == 0; + + return prevVal; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Override @Nullable public CacheObject localPreviousValue(int idx) { + assert idx == 0; + + return locPrevVal; + } + + /** + * @param idx Key index. + * @return Entry processor. + */ + @Override @Nullable public EntryProcessor entryProcessor(int idx) { + assert idx == 0; + + return entryProcessor; + } + + /** + * @param idx Near key index. + * @return Value. + */ + @Override @Nullable public CacheObject nearValue(int idx) { + assert idx == 0; + + return nearVal; + } + + /** + * @param idx Key index. + * @return Transform closure. + */ + @Override @Nullable public EntryProcessor nearEntryProcessor(int idx) { + assert idx == 0; + + return nearEntryProcessor; + } + + /** + * @param idx Index. + * @return Conflict version. + */ + @Override @Nullable public GridCacheVersion conflictVersion(int idx) { + assert idx == 0; + + return conflictVer; + } + + /** + * @param idx Index. + * @return TTL. + */ + @Override public long ttl(int idx) { + assert idx == 0; + + return ttl; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + @Override public long nearTtl(int idx) { + assert idx == 0; + + return nearTtl; + } + + /** + * @param idx Index. + * @return Conflict expire time. + */ + @Override public long conflictExpireTime(int idx) { + assert idx == 0; + + return conflictExpireTime; + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + @Override public long nearExpireTime(int idx) { + assert idx == 0; + + return nearExpireTime; + } + + /** + * @return {@code True} if on response flag changed. + */ + @Override public boolean onResponse() { + return !onRes && (onRes = true); + } + + /** + * @return Optional arguments for entry processor. + */ + @Override @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObject(key, cctx); + + prepareMarshalCacheObject(val, cctx); + + prepareMarshalCacheObject(nearKey, cctx); + + prepareMarshalCacheObject(nearVal, cctx); + + prepareMarshalCacheObject(prevVal, cctx); + + if (forceTransformBackups) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + + if (entryProcessorBytes == null) + entryProcessorBytes = marshal(entryProcessor, cctx); + + if (nearEntryProcessorBytes == null) + nearEntryProcessorBytes = marshal(nearEntryProcessor, cctx); + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObject(key, cctx, ldr); + + finishUnmarshalCacheObject(val, cctx, ldr); + + finishUnmarshalCacheObject(nearKey, cctx, ldr); + + finishUnmarshalCacheObject(nearVal, cctx, ldr); + + finishUnmarshalCacheObject(prevVal, cctx, ldr); + + if (forceTransformBackups) { + if (entryProcessor == null) + entryProcessor = unmarshal(entryProcessorBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + + if (nearEntryProcessor == null) + nearEntryProcessor = unmarshal(nearEntryProcessorBytes, ctx, ldr); + } + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeLong("conflictExpireTime", conflictExpireTime)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeMessage("conflictVer", conflictVer)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeByteArray("entryProcessorBytes", entryProcessorBytes)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeMessage("key", key)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeByteArray("nearEntryProcessorBytes", nearEntryProcessorBytes)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeLong("nearExpireTime", nearExpireTime)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeMessage("nearKey", nearKey)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeLong("nearTtl", nearTtl)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeMessage("nearVal", nearVal)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeMessage("prevVal", prevVal)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeLong("ttl", ttl)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeLong("updateCntr", updateCntr)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeMessage("val", val)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("writeVer", writeVer)) + 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: + conflictExpireTime = reader.readLong("conflictExpireTime"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictVer = reader.readMessage("conflictVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + entryProcessorBytes = reader.readByteArray("entryProcessorBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + forceTransformBackups = reader.readBoolean("forceTransformBackups"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + key = reader.readMessage("key"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + nearEntryProcessorBytes = reader.readByteArray("nearEntryProcessorBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + nearExpireTime = reader.readLong("nearExpireTime"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + nearKey = reader.readMessage("nearKey"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + nearTtl = reader.readLong("nearTtl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + nearVal = reader.readMessage("nearVal"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + prevVal = reader.readMessage("prevVal"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 17: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + byte syncModeOrd; + + syncModeOrd = reader.readByte("syncMode"); + + if (!reader.isLastRead()) + return false; + + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + + reader.incrementState(); + + case 19: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + ttl = reader.readLong("ttl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + updateCntr = reader.readLong("updateCntr"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + val = reader.readMessage("val"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + writeVer = reader.readMessage("writeVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridDhtAtomicSingleUpdateRequest.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return -25; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 25; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicSingleUpdateRequest.class, this, "super", super.toString()); + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java new file mode 100644 index 0000000000000..6a69cccdf367c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java @@ -0,0 +1,296 @@ +/* + * + * * 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.atomic; + +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.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; +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; +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; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class GridDhtAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Future version. */ + private GridCacheVersion futVer; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List failedKeys; + + /** Update error. */ + @GridDirectTransient + private IgniteCheckedException err; + + /** Serialized update error. */ + private byte[] errBytes; + + /** Evicted readers. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearEvicted; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicSingleUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param futVer Future version. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { + this.cacheId = cacheId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Future version. + */ + @Override public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + @Override public void onError(IgniteCheckedException err) { + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Failed keys. + */ + @Override public Collection failedKeys() { + return failedKeys; + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + @Override public void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ArrayList<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * @return Evicted readers. + */ + @Override public Collection nearEvicted() { + return nearEvicted; + } + + /** + * Adds near evicted key.. + * + * @param key Evicted key. + */ + @Override public void addNearEvicted(KeyCacheObject key) { + if (nearEvicted == null) + nearEvicted = new ArrayList<>(); + + nearEvicted.add(key); + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(failedKeys, cctx); + + prepareMarshalCacheObjects(nearEvicted, cctx); + + if (errBytes == null) + errBytes = ctx.marshaller().marshal(err); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridDhtAtomicSingleUpdateResponse.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 39; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 7; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicSingleUpdateResponse.class, this); + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 3a31700dcedfc..e19a11a5d5611 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -35,6 +35,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -237,19 +238,34 @@ public void addWriteEntry(GridDhtCacheEntry entry, GridDhtAtomicUpdateRequest updateReq = mappings.get(nodeId); if (updateReq == null) { - updateReq = new GridDhtAtomicUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); + if (this.updateReq instanceof GridNearAtomicSingleUpdateRequest) + updateReq = new GridDhtAtomicSingleUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); + else + updateReq = new GridDhtAtomicMultipleUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); mappings.put(nodeId, updateReq); } @@ -309,19 +325,34 @@ public void addNearWriteEntries(Iterable readers, if (node == null) continue; - updateReq = new GridDhtAtomicUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); + if (this.updateReq instanceof GridNearAtomicSingleUpdateRequest) + updateReq = new GridDhtAtomicSingleUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); + else + updateReq = new GridDhtAtomicMultipleUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); mappings.put(nodeId, updateReq); } @@ -348,7 +379,8 @@ public void addNearWriteEntries(Iterable readers, if (!mappings.isEmpty()) { Collection hndKeys = new ArrayList<>(keys.size()); - exit: for (GridDhtAtomicUpdateRequest req : mappings.values()) { + exit: + for (GridDhtAtomicUpdateRequest req : mappings.values()) { for (int i = 0; i < req.size(); i++) { KeyCacheObject key = req.key(i); @@ -416,7 +448,7 @@ public void map() { if (log.isDebugEnabled()) log.debug("Sending DHT atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); + cctx.io().send(req.nodeId(), (GridCacheMessage)req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ignored) { U.warn(log, "Failed to send update request to backup node because it left grid: " + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java index 7cc276f1bcaab..0ab67a686ebaf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java @@ -1,248 +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 + * * 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. * - * 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.atomic; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import javax.cache.processor.EntryProcessor; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; -import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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; -import org.apache.ignite.internal.util.GridLongList; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.cache.processor.EntryProcessor; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.UUID; -/** - * Lite dht cache backup update request. - */ -public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID. */ - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Write version. */ - private GridCacheVersion writeVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List vals; - - /** Previous values. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List prevVals; - - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; - - /** TTLs. */ - private GridLongList ttls; - - /** Conflict expire time. */ - private GridLongList conflictExpireTimes; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Near cache keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearKeys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; - - /** Force transform backups flag. */ - private boolean forceTransformBackups; - - /** Entry processors. */ - @GridDirectTransient - private List> entryProcessors; - - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; - - /** Near entry processors. */ - @GridDirectTransient - private List> nearEntryProcessors; - - /** Near entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List nearEntryProcessorsBytes; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Partition. */ - private GridLongList updateCntrs; - - /** On response flag. Access should be synced on future. */ - @GridDirectTransient - private boolean onRes; - - /** */ - @GridDirectTransient - private List partIds; - - /** */ - @GridDirectTransient - private List locPrevVals; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicUpdateRequest() { - // No-op. - } - - /** - * Constructor. - * - * @param cacheId Cache ID. - * @param nodeId Node ID. - * @param futVer Future version. - * @param writeVer Write version for cache values. - * @param invokeArgs Optional arguments for entry processor. - * @param syncMode Cache write synchronization mode. - * @param topVer Topology version. - * @param forceTransformBackups Force transform backups flag. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicUpdateRequest( - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - GridCacheVersion writeVer, - CacheWriteSynchronizationMode syncMode, - @NotNull AffinityTopologyVersion topVer, - boolean forceTransformBackups, - UUID subjId, - int taskNameHash, - Object[] invokeArgs, - boolean addDepInfo, - boolean keepBinary - ) { - assert invokeArgs == null || forceTransformBackups; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.writeVer = writeVer; - this.syncMode = syncMode; - this.topVer = topVer; - this.forceTransformBackups = forceTransformBackups; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.invokeArgs = invokeArgs; - this.addDepInfo = addDepInfo; - this.keepBinary = keepBinary; - - keys = new ArrayList<>(); - partIds = new ArrayList<>(); - locPrevVals = new ArrayList<>(); - - if (forceTransformBackups) { - entryProcessors = new ArrayList<>(); - entryProcessorsBytes = new ArrayList<>(); - } - else - vals = new ArrayList<>(); - } +public interface GridDhtAtomicUpdateRequest { - /** - * @return Force transform backups flag. - */ - public boolean forceTransformBackups() { - return forceTransformBackups; - } + boolean forceTransformBackups(); - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param addPrevVal If {@code true} adds previous value. - * @param prevVal Previous value. - */ - public void addWriteValue(KeyCacheObject key, + void addWriteValue(KeyCacheObject key, @Nullable CacheObject val, EntryProcessor entryProcessor, long ttl, @@ -251,815 +47,85 @@ public void addWriteValue(KeyCacheObject key, boolean addPrevVal, int partId, @Nullable CacheObject prevVal, - @Nullable Long updateIdx) { - keys.add(key); - - partIds.add(partId); - - locPrevVals.add(prevVal); - - if (forceTransformBackups) { - assert entryProcessor != null; - - entryProcessors.add(entryProcessor); - } - else - vals.add(val); - - if (addPrevVal) { - if (prevVals == null) - prevVals = new ArrayList<>(); - - prevVals.add(prevVal); - } - - if (updateIdx != null) { - if (updateCntrs == null) - updateCntrs = new GridLongList(); - - updateCntrs.add(updateIdx); - } - - // In case there is no conflict, do not create the list. - if (conflictVer != null) { - if (conflictVers == null) { - conflictVers = new ArrayList<>(); - - for (int i = 0; i < keys.size() - 1; i++) - conflictVers.add(null); - } - - conflictVers.add(conflictVer); - } - else if (conflictVers != null) - conflictVers.add(null); - - if (ttl >= 0) { - if (ttls == null) { - ttls = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - ttls.add(CU.TTL_NOT_CHANGED); - } - } + @Nullable Long updateIdx); - if (ttls != null) - ttls.add(ttl); - - if (conflictExpireTime >= 0) { - if (conflictExpireTimes == null) { - conflictExpireTimes = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - } - - if (conflictExpireTimes != null) - conflictExpireTimes.add(conflictExpireTime); - } - - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL. - * @param expireTime Expire time. - */ - public void addNearWriteValue(KeyCacheObject key, + void addNearWriteValue(KeyCacheObject key, @Nullable CacheObject val, EntryProcessor entryProcessor, long ttl, - long expireTime) { - if (nearKeys == null) { - nearKeys = new ArrayList<>(); - - if (forceTransformBackups) { - nearEntryProcessors = new ArrayList<>(); - nearEntryProcessorsBytes = new ArrayList<>(); - } - else - nearVals = new ArrayList<>(); - } - - nearKeys.add(key); - - if (forceTransformBackups) { - assert entryProcessor != null; - - nearEntryProcessors.add(entryProcessor); - } - else - nearVals.add(val); - - if (ttl >= 0) { - if (nearTtls == null) { - nearTtls = new GridLongList(nearKeys.size()); - - for (int i = 0; i < nearKeys.size() - 1; i++) - nearTtls.add(CU.TTL_NOT_CHANGED); - } - } - - if (nearTtls != null) - nearTtls.add(ttl); - - if (expireTime >= 0) { - if (nearExpireTimes == null) { - nearExpireTimes = new GridLongList(nearKeys.size()); - - for (int i = 0; i < nearKeys.size() - 1; i++) - nearExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - } - - if (nearExpireTimes != null) - nearExpireTimes.add(expireTime); - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID. - */ - public UUID nodeId() { - return nodeId; - } - - /** - * @return Subject ID. - */ - public UUID subjectId() { - return subjId; - } - - /** - * @return Task name. - */ - public int taskNameHash() { - return taskNameHash; - } - - /** - * @return Keys size. - */ - public int size() { - return keys.size(); - } - - /** - * @return Keys size. - */ - public int nearSize() { - return nearKeys != null ? nearKeys.size() : 0; - } - - /** - * @return Version assigned on primary node. - */ - public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * @return Write version. - */ - public GridCacheVersion writeVersion() { - return writeVer; - } - - /** - * @return Cache write synchronization mode. - */ - public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** - * @return Topology version. - */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** - * @return Keys. - */ - public Collection keys() { - return keys; - } - - /** - * @param idx Key index. - * @return Key. - */ - public KeyCacheObject key(int idx) { - return keys.get(idx); - } - - /** - * @param idx Partition index. - * @return Partition id. - */ - public int partitionId(int idx) { - return partIds.get(idx); - } - - /** - * @param updCntr Update counter. - * @return Update counter. - */ - public Long updateCounter(int updCntr) { - if (updateCntrs != null && updCntr < updateCntrs.size()) - return updateCntrs.get(updCntr); - - return null; - } - - /** - * @param idx Near key index. - * @return Key. - */ - public KeyCacheObject nearKey(int idx) { - return nearKeys.get(idx); - } - - /** - * @return Keep binary flag. - */ - public boolean keepBinary() { - return keepBinary; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Nullable public CacheObject value(int idx) { - if (vals != null) - return vals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Nullable public CacheObject previousValue(int idx) { - if (prevVals != null) - return prevVals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Nullable public CacheObject localPreviousValue(int idx) { - return locPrevVals.get(idx); - } - - /** - * @param idx Key index. - * @return Entry processor. - */ - @Nullable public EntryProcessor entryProcessor(int idx) { - return entryProcessors == null ? null : entryProcessors.get(idx); - } - - /** - * @param idx Near key index. - * @return Value. - */ - @Nullable public CacheObject nearValue(int idx) { - if (nearVals != null) - return nearVals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Transform closure. - */ - @Nullable public EntryProcessor nearEntryProcessor(int idx) { - return nearEntryProcessors == null ? null : nearEntryProcessors.get(idx); - } - - /** - * @param idx Index. - * @return Conflict version. - */ - @Nullable public GridCacheVersion conflictVersion(int idx) { - if (conflictVers != null) { - assert idx >= 0 && idx < conflictVers.size(); - - return conflictVers.get(idx); - } - - return null; - } - - /** - * @param idx Index. - * @return TTL. - */ - public long ttl(int idx) { - if (ttls != null) { - assert idx >= 0 && idx < ttls.size(); - - return ttls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - public long nearTtl(int idx) { - if (nearTtls != null) { - assert idx >= 0 && idx < nearTtls.size(); - - return nearTtls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** - * @param idx Index. - * @return Conflict expire time. - */ - public long conflictExpireTime(int idx) { - if (conflictExpireTimes != null) { - assert idx >= 0 && idx < conflictExpireTimes.size(); - - return conflictExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - public long nearExpireTime(int idx) { - if (nearExpireTimes != null) { - assert idx >= 0 && idx < nearExpireTimes.size(); - - return nearExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** - * @return {@code True} if on response flag changed. - */ - public boolean onResponse() { - return !onRes && (onRes = true); - } - - /** - * @return Optional arguments for entry processor. - */ - @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - prepareMarshalCacheObjects(vals, cctx); - - prepareMarshalCacheObjects(nearKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); - - prepareMarshalCacheObjects(prevVals, cctx); - - if (forceTransformBackups) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); - - if (nearEntryProcessorsBytes == null) - nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - finishUnmarshalCacheObjects(vals, cctx, ldr); - - finishUnmarshalCacheObjects(nearKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearVals, cctx, ldr); - - finishUnmarshalCacheObjects(prevVals, cctx, ldr); - - if (forceTransformBackups) { - if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - - if (nearEntryProcessors == null) - nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); - } - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeMessage("conflictExpireTimes", conflictExpireTimes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeCollection("nearEntryProcessorsBytes", nearEntryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeCollection("nearKeys", nearKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeMessage("nearTtls", nearTtls)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeCollection("prevVals", prevVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 17: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeMessage("ttls", ttls)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeMessage("updateCntrs", updateCntrs)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("writeVer", writeVer)) - 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: - conflictExpireTimes = reader.readMessage("conflictExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - forceTransformBackups = reader.readBoolean("forceTransformBackups"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - keys = reader.readCollection("keys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - nearEntryProcessorsBytes = reader.readCollection("nearEntryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - nearExpireTimes = reader.readMessage("nearExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - nearKeys = reader.readCollection("nearKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - nearTtls = reader.readMessage("nearTtls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); + long expireTime); - case 15: - nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + int lookupIndex(); - if (!reader.isLastRead()) - return false; + UUID nodeId(); - reader.incrementState(); + UUID subjectId(); - case 16: - prevVals = reader.readCollection("prevVals", MessageCollectionItemType.MSG); + int taskNameHash(); - if (!reader.isLastRead()) - return false; + int size(); - reader.incrementState(); + int nearSize(); - case 17: - subjId = reader.readUuid("subjId"); + GridCacheVersion futureVersion(); - if (!reader.isLastRead()) - return false; + GridCacheVersion writeVersion(); - reader.incrementState(); + CacheWriteSynchronizationMode writeSynchronizationMode(); - case 18: - byte syncModeOrd; + AffinityTopologyVersion topologyVersion(); - syncModeOrd = reader.readByte("syncMode"); + Collection keys(); - if (!reader.isLastRead()) - return false; + KeyCacheObject key(int idx); - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + int partitionId(int idx); - reader.incrementState(); + Long updateCounter(int updCntr); - case 19: - taskNameHash = reader.readInt("taskNameHash"); + KeyCacheObject nearKey(int idx); - if (!reader.isLastRead()) - return false; + boolean keepBinary(); - reader.incrementState(); + @Nullable CacheObject value(int idx); - case 20: - topVer = reader.readMessage("topVer"); + @Nullable CacheObject previousValue(int idx); - if (!reader.isLastRead()) - return false; + @Nullable CacheObject localPreviousValue(int idx); - reader.incrementState(); + @Nullable EntryProcessor entryProcessor(int idx); - case 21: - ttls = reader.readMessage("ttls"); + @Nullable CacheObject nearValue(int idx); - if (!reader.isLastRead()) - return false; + @Nullable EntryProcessor nearEntryProcessor(int idx); - reader.incrementState(); + @Nullable GridCacheVersion conflictVersion(int idx); - case 22: - updateCntrs = reader.readMessage("updateCntrs"); + long ttl(int idx); - if (!reader.isLastRead()) - return false; + long nearTtl(int idx); - reader.incrementState(); + long conflictExpireTime(int idx); - case 23: - vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + long nearExpireTime(int idx); - if (!reader.isLastRead()) - return false; + boolean onResponse(); - reader.incrementState(); + @Nullable Object[] invokeArguments(); - case 24: - writeVer = reader.readMessage("writeVer"); + void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; - if (!reader.isLastRead()) - return false; + void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; - reader.incrementState(); + boolean addDeploymentInfo(); - } + boolean writeTo(ByteBuffer buf, MessageWriter writer); - return reader.afterMessageRead(GridDhtAtomicUpdateRequest.class); - } + boolean readFrom(ByteBuffer buf, MessageReader reader); - /** {@inheritDoc} */ - @Override public byte directType() { - return 38; - } + byte directType(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 25; - } + byte fieldsCount(); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicUpdateRequest.class, this, "super", super.toString()); - } + IgniteCheckedException classError(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java index 8f1d9a2da9259..a74fed60846da 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java @@ -1,297 +1,63 @@ /* - * 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 + * * 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. * - * 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.atomic; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; 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.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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; -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; +import java.nio.ByteBuffer; +import java.util.Collection; -/** - * DHT atomic cache backup update response. - */ -public class GridDhtAtomicUpdateResponse extends GridCacheMessage implements GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Future version. */ - private GridCacheVersion futVer; - - /** Failed keys. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List failedKeys; - - /** Update error. */ - @GridDirectTransient - private IgniteCheckedException err; - - /** Serialized update error. */ - private byte[] errBytes; - - /** Evicted readers. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearEvicted; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param futVer Future version. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { - this.cacheId = cacheId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Future version. - */ - public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - public void onError(IgniteCheckedException err){ - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Failed keys. - */ - public Collection failedKeys() { - return failedKeys; - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - public void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ArrayList<>(); - - failedKeys.add(key); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * @return Evicted readers. - */ - public Collection nearEvicted() { - return nearEvicted; - } - - /** - * Adds near evicted key.. - * - * @param key Evicted key. - */ - public void addNearEvicted(KeyCacheObject key) { - if (nearEvicted == null) - nearEvicted = new ArrayList<>(); - - nearEvicted.add(key); - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(failedKeys, cctx); - - prepareMarshalCacheObjects(nearEvicted, cctx); - - if (errBytes == null) - errBytes = ctx.marshaller().marshal(err); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; +public interface GridDhtAtomicUpdateResponse { + int lookupIndex(); - reader.incrementState(); + GridCacheVersion futureVersion(); - case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + void onError(IgniteCheckedException err); - if (!reader.isLastRead()) - return false; + IgniteCheckedException error(); - reader.incrementState(); + Collection failedKeys(); - case 5: - futVer = reader.readMessage("futVer"); + void addFailedKey(KeyCacheObject key, Throwable e); - if (!reader.isLastRead()) - return false; + Collection nearEvicted(); - reader.incrementState(); + void addNearEvicted(KeyCacheObject key); - case 6: - nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); + void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; - if (!reader.isLastRead()) - return false; + void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; - reader.incrementState(); + boolean addDeploymentInfo(); - } + boolean writeTo(ByteBuffer buf, MessageWriter writer); - return reader.afterMessageRead(GridDhtAtomicUpdateResponse.class); - } + boolean readFrom(ByteBuffer buf, MessageReader reader); - /** {@inheritDoc} */ - @Override public byte directType() { - return 39; - } + byte directType(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 7; - } + byte fieldsCount(); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicUpdateResponse.class, this); - } + long messageId(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java index b3f7e74fefd4b..d6eabd40adc92 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java @@ -593,7 +593,7 @@ public void addNearTtl(int keyIdx, long ttl, long expireTime) { } - return reader.afterMessageRead(GridNearAtomicMultipleUpdateResponse.class); + return reader.afterMessageRead(GridNearAtomicSingleUpdateResponse.class); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 5aef8e76b7915..168076a4af169 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -43,9 +43,9 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java index 50a6114d1195a..0633a1e247f42 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java @@ -27,7 +27,7 @@ import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.managers.communication.GridIoMessage; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; import org.apache.ignite.lang.IgniteInClosure; @@ -140,7 +140,7 @@ protected void checkMessages(boolean clientMode, commSpi.registerMessage(GridNearAtomicMultipleUpdateRequest.class); commSpi.registerMessage(GridNearAtomicSingleUpdateRequest.class); - commSpi.registerMessage(GridDhtAtomicUpdateRequest.class); + commSpi.registerMessage(GridDhtAtomicMultipleUpdateRequest.class); int putCnt = 15; @@ -210,7 +210,7 @@ private int nearRequestsCount(TestCommunicationSpi commSpi) { * @return Count. */ private int dhtRequestsCount(TestCommunicationSpi commSpi) { - return commSpi.messageCount(GridDhtAtomicUpdateRequest.class); + return commSpi.messageCount(GridDhtAtomicMultipleUpdateRequest.class); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java index 0e7755bee8e9c..e3adc21f26207 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java @@ -480,7 +480,7 @@ private boolean delayMessage(GridIoMessage msg) { return delay && ( (origMsg instanceof GridNearAtomicMultipleUpdateRequest) || (origMsg instanceof GridNearAtomicSingleUpdateRequest) || - (origMsg instanceof GridDhtAtomicUpdateRequest) + (origMsg instanceof GridDhtAtomicMultipleUpdateRequest) ); } } From cd07298f31be580b8341e0409b4669376e90f1bd Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 17:46:37 +0300 Subject: [PATCH 26/34] ignite-2523 : Removed unnecessary fields from GridDhtAtomicSingleUpdateRequest. --- .../GridDhtAtomicSingleUpdateRequest.java | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java index c842270f07fc4..0c0dd191bd1e8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java @@ -112,69 +112,12 @@ public class GridDhtAtomicSingleUpdateRequest extends GridCacheMessage implement @GridDirectTransient private CacheObject locPrevVal; - /** Keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List vals; - - /** Previous values. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List prevVals; - - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; - - /** TTLs. */ - private GridLongList ttls; - - /** Conflict expire time. */ - private GridLongList conflictExpireTimes; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - /** Write synchronization mode. */ private CacheWriteSynchronizationMode syncMode; - /** Near cache keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearKeys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; - /** Force transform backups flag. */ private boolean forceTransformBackups; - /** Entry processors. */ - @GridDirectTransient - private List> entryProcessors; - - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; - - /** Near entry processors. */ - @GridDirectTransient - private List> nearEntryProcessors; - - /** Near entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List nearEntryProcessorsBytes; - /** Optional arguments for entry processor. */ @GridDirectTransient private Object[] invokeArgs; @@ -188,21 +131,10 @@ public class GridDhtAtomicSingleUpdateRequest extends GridCacheMessage implement /** Task name hash. */ private int taskNameHash; - /** Partition. */ - private GridLongList updateCntrs; - /** On response flag. Access should be synced on future. */ @GridDirectTransient private boolean onRes; - /** */ - @GridDirectTransient - private List partIds; - - /** */ - @GridDirectTransient - private List locPrevVals; - /** Keep binary flag. */ private boolean keepBinary; @@ -256,17 +188,6 @@ public GridDhtAtomicSingleUpdateRequest( this.invokeArgs = invokeArgs; this.addDepInfo = addDepInfo; this.keepBinary = keepBinary; - - keys = new ArrayList<>(); - partIds = new ArrayList<>(); - locPrevVals = new ArrayList<>(); - - if (forceTransformBackups) { - entryProcessors = new ArrayList<>(); - entryProcessorsBytes = new ArrayList<>(); - } - else - vals = new ArrayList<>(); } /** From 1256485bd2b2ab6cb16b0778651584739747ba04 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Tue, 9 Feb 2016 17:52:38 +0300 Subject: [PATCH 27/34] ignite-2523 : GridDhtAtomicSingleUpdateResponse optimized implementation. --- .../GridDhtAtomicSingleUpdateResponse.java | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java index 6a69cccdf367c..044efa9c53929 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java @@ -37,6 +37,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; public class GridDhtAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateResponse { @@ -49,10 +50,11 @@ public class GridDhtAtomicSingleUpdateResponse extends GridCacheMessage implemen /** Future version. */ private GridCacheVersion futVer; - /** Failed keys. */ @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List failedKeys; + private KeyCacheObject failedKey; + + @GridToStringInclude + private KeyCacheObject nearEvicted; /** Update error. */ @GridDirectTransient @@ -61,11 +63,6 @@ public class GridDhtAtomicSingleUpdateResponse extends GridCacheMessage implemen /** Serialized update error. */ private byte[] errBytes; - /** Evicted readers. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearEvicted; - /** * Empty constructor required by {@link Externalizable}. */ @@ -114,7 +111,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b * @return Failed keys. */ @Override public Collection failedKeys() { - return failedKeys; + return failedKey != null ? Collections.singletonList(failedKey) : null; } /** @@ -124,10 +121,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b * @param e Error cause. */ @Override public void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ArrayList<>(); - - failedKeys.add(key); + failedKey = key; if (err == null) err = new IgniteCheckedException("Failed to update keys on primary node."); @@ -139,7 +133,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b * @return Evicted readers. */ @Override public Collection nearEvicted() { - return nearEvicted; + return nearEvicted != null ? Collections.singletonList(nearEvicted) : null; } /** @@ -148,10 +142,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b * @param key Evicted key. */ @Override public void addNearEvicted(KeyCacheObject key) { - if (nearEvicted == null) - nearEvicted = new ArrayList<>(); - - nearEvicted.add(key); + nearEvicted = key; } /** {@inheritDoc} */ @@ -160,9 +151,9 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b GridCacheContext cctx = ctx.cacheContext(cacheId); - prepareMarshalCacheObjects(failedKeys, cctx); + prepareMarshalCacheObject(failedKey, cctx); - prepareMarshalCacheObjects(nearEvicted, cctx); + prepareMarshalCacheObject(nearEvicted, cctx); if (errBytes == null) errBytes = ctx.marshaller().marshal(err); @@ -174,9 +165,9 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b GridCacheContext cctx = ctx.cacheContext(cacheId); - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + finishUnmarshalCacheObject(failedKey, cctx, ldr); - finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); + finishUnmarshalCacheObject(nearEvicted, cctx, ldr); if (errBytes != null && err == null) err = ctx.marshaller().unmarshal(errBytes, ldr); @@ -209,7 +200,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b writer.incrementState(); case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + if (!writer.writeMessage("failedKey", failedKey)) return false; writer.incrementState(); @@ -221,7 +212,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b writer.incrementState(); case 6: - if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) + if (!writer.writeMessage("nearEvicted", nearEvicted)) return false; writer.incrementState(); @@ -251,7 +242,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b reader.incrementState(); case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + failedKey = reader.readMessage("failedKey"); if (!reader.isLastRead()) return false; @@ -267,7 +258,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b reader.incrementState(); case 6: - nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); + nearEvicted = reader.readMessage("nearEvicted"); if (!reader.isLastRead()) return false; @@ -281,7 +272,7 @@ public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, b /** {@inheritDoc} */ @Override public byte directType() { - return 39; + return -26; } /** {@inheritDoc} */ From d3aab05fe8fad8d88ad3690d618c6d7ed5d14cb2 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 19 Feb 2016 10:23:22 +0300 Subject: [PATCH 28/34] ignite-2654 : Merge. --- .../distributed/near/GridNearLockFuture.java | 115 +++++++++++++----- 1 file changed, 83 insertions(+), 32 deletions(-) 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 bf9976873d501..599f9ea907906 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 @@ -84,6 +84,8 @@ public final class GridNearLockFuture extends GridFutureAdapter implements GridCacheMvccFuture { + private static final UUID DUMMY_UUID = new UUID(0L, 0L); + /** */ private static final long serialVersionUID = 0L; @@ -164,7 +166,9 @@ public final class GridNearLockFuture extends GridFutureAdapter private final boolean keepBinary; /** Mappings of sent requests. */ - private final Map sent = new HashMap<>(); + private final Map sent = new HashMap<>(); + + private final AtomicInteger counter = new AtomicInteger(); /** * @param cctx Registry. @@ -467,7 +471,12 @@ void onResult(UUID nodeId, GridNearLockResponse res) { if (log.isDebugEnabled()) log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); - IgniteUuid miniId = res.miniId(); + int miniId; + + if (res instanceof GridNearLockResponseV2) + miniId = ((GridNearLockResponseV2)res).miniId(); + else + miniId = (int)((GridNearLockResponseV1)res).miniId().localId(); GridNearLockMapping mapping; @@ -1177,31 +1186,70 @@ private void map(Iterable keys, boolean remap, boolean topLocked first = false; } - req = new GridNearLockRequest( - cctx.cacheId(), - topVer, - cctx.nodeId(), - threadId, - futId, - lockVer, - inTx(), - implicitTx(), - implicitSingleTx(), - read, - retval, - isolation(), - isInvalidate(), - timeout, - mappedKeys.size(), - inTx() ? tx.size() : mappedKeys.size(), - inTx() && tx.syncCommit(), - inTx() ? tx.subjectId() : null, - inTx() ? tx.taskNameHash() : 0, - read ? accessTtl : -1L, - skipStore, - keepBinary, - clientFirst, - cctx.deploymentEnabled()); + boolean optimize = true; + + Collection topNodes = CU.affinityNodes(cctx, topVer); + + for (ClusterNode topNode : topNodes) { + if (topNode.version().compareTo(cctx.localNode().version()) < 0) { + optimize = false; + + break; + } + } + + if (optimize) + req = new GridNearLockRequestV2( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); + else + req = new GridNearLockRequestV1( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); mapping.request(req); } @@ -1312,13 +1360,16 @@ private void proceedMapping0() if (filter != null && filter.length != 0) req.filter(filter, cctx); - IgniteUuid id = IgniteUuid.randomUuid(); + int miniId = counter.incrementAndGet(); synchronized (this) { - sent.put(id, map); + sent.put(miniId, map); } - req.miniId(id); + if (req instanceof GridNearLockRequestV2) + ((GridNearLockRequestV2)req).miniId(miniId); + else + ((GridNearLockRequestV1)req).miniId(new IgniteUuid(DUMMY_UUID, miniId)); if (node.isLocal()) { if (log.isDebugEnabled()) { @@ -1353,7 +1404,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, (GridCacheMessage)req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { onDone(ex); @@ -1366,7 +1417,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, (GridCacheMessage)req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { tx.removeMapping(node.id()); From 3d6a95260000d7036696a5929d7fd61d9600d990 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 19 Feb 2016 10:46:30 +0300 Subject: [PATCH 29/34] ignite-2654 : GridNearLockResponse optimization. --- .../communication/GridIoMessageFactory.java | 2 +- .../dht/GridDhtTransactionalCacheAdapter.java | 66 ++++++++++++------- .../near/GridNearLockResponse.java | 4 ++ 3 files changed, 48 insertions(+), 24 deletions(-) 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 f92d728445dcf..9ac507a97f554 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 @@ -733,7 +733,7 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; - case 127: + case 126: msg = new GridNearLockResponseV2(); break; 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 214444a58d6b9..92c3ee1be2a6e 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 @@ -41,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -54,6 +55,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote; @@ -958,7 +960,7 @@ public IgniteInternalFuture lockAllAsync( assert !t.empty(); // Create response while holding locks. - final GridNearLockResponseV1 resp = createLockReply(nearNode, + final GridNearLockResponse resp = createLockReply(nearNode, entries, req, t, @@ -1011,7 +1013,7 @@ public IgniteInternalFuture lockAllAsync( else if (!b) e = new GridCacheLockTimeoutException(req.version()); - GridNearLockResponseV1 res = createLockReply(nearNode, + GridNearLockResponse res = createLockReply(nearNode, entries, req, null, @@ -1098,7 +1100,7 @@ private GridNearLockResponse sendClientLockRemapResponse(ClusterNode nearNode, * @param err Error. * @return Response. */ - private GridNearLockResponseV1 createLockReply( + private GridNearLockResponse createLockReply( ClusterNode nearNode, List entries, GridNearLockRequest req, @@ -1108,25 +1110,30 @@ private GridNearLockResponseV1 createLockReply( assert mappedVer != null; assert tx == null || tx.xidVersion().equals(mappedVer); - IgniteUuid miniId; + GridNearLockResponse res; - if (req instanceof GridNearLockRequestV1) - miniId = ((GridNearLockRequestV1)req).miniId(); + if (req instanceof GridNearLockRequestV2) + res = new GridNearLockResponseV2(ctx.cacheId(), + req.version(), + req.futureId(), + ((GridNearLockRequestV2)req).miniId(), + tx != null && tx.onePhaseCommit(), + entries.size(), + err, + null, + ctx.deploymentEnabled()); else - miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); - - try { - // Send reply back to originating near node. - GridNearLockResponseV1 res = new GridNearLockResponseV1(ctx.cacheId(), + res = new GridNearLockResponseV1(ctx.cacheId(), req.version(), req.futureId(), - miniId, + ((GridNearLockRequestV1)req).miniId(), tx != null && tx.onePhaseCommit(), entries.size(), err, null, ctx.deploymentEnabled()); + try { if (err == null) { res.pending(localDhtPendingVersions(entries, mappedVer)); @@ -1229,15 +1236,28 @@ private GridNearLockResponseV1 createLockReply( U.error(log, "Failed to get value for lock reply message for node [node=" + U.toShortString(nearNode) + ", req=" + req + ']', e); - return new GridNearLockResponseV1(ctx.cacheId(), - req.version(), - req.futureId(), - miniId, - false, - entries.size(), - e, - null, - ctx.deploymentEnabled()); + if (req instanceof GridNearLockRequestV2) + res = new GridNearLockResponseV2(ctx.cacheId(), + req.version(), + req.futureId(), + ((GridNearLockRequestV2)req).miniId(), + false, + entries.size(), + e, + null, + ctx.deploymentEnabled()); + else + res = new GridNearLockResponseV1(ctx.cacheId(), + req.version(), + req.futureId(), + ((GridNearLockRequestV1)req).miniId(), + false, + entries.size(), + e, + null, + ctx.deploymentEnabled()); + + return res; } } @@ -1253,7 +1273,7 @@ private void sendLockReply( ClusterNode nearNode, @Nullable IgniteInternalTx tx, GridNearLockRequest req, - GridNearLockResponseV1 res + GridNearLockResponse res ) { Throwable err = res.error(); @@ -1264,7 +1284,7 @@ private void sendLockReply( try { // Don't send reply message to this node or if lock was cancelled. if (!nearNode.id().equals(ctx.nodeId()) && !X.hasCause(err, GridDistributedLockCancelledException.class)) - ctx.io().send(nearNode, res, ctx.ioPolicy()); + ctx.io().send(nearNode, (GridCacheMessage)res, ctx.ioPolicy()); } catch (IgniteCheckedException e) { U.error(log, "Failed to send lock reply to originating node (will rollback transaction) [node=" + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java index dbd53b414a3f5..8378d4b4ba208 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java @@ -41,4 +41,8 @@ void addValueBytes( Collection rolledbackVersions(); IgniteUuid futureId(); + + void completedVersions(Collection committedVers, Collection rolledbackVers); + + void error(Throwable err); } From e125dadfc45a013aa3a86fe07ee8f0ad90db657a Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 19 Feb 2016 13:22:33 +0300 Subject: [PATCH 30/34] ignite-2654 : Optimized GridNearLockRequestV2. --- .../near/GridNearLockRequestV2.java | 156 ++++-------------- 1 file changed, 31 insertions(+), 125 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java index f1cd5421ce035..4ddd4534afede 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java @@ -38,14 +38,7 @@ public class GridNearLockRequestV2 extends GridDistributedLockRequest implements /** Filter. */ private CacheEntryPredicate[] filter; - /** Implicit flag. */ - private boolean implicitTx; - - /** Implicit transaction with one key flag. */ - private boolean implicitSingleTx; - - /** Flag is kept for backward compatibility. */ - private boolean onePhaseCommit; + private byte flags; /** Array of mapped DHT versions for this entry. */ @GridToStringInclude @@ -57,21 +50,9 @@ public class GridNearLockRequestV2 extends GridDistributedLockRequest implements /** Task name hash. */ private int taskNameHash; - /** Has transforms flag. */ - private boolean hasTransforms; - - /** Sync commit flag. */ - private boolean syncCommit; - /** TTL for read operation. */ private long accessTtl; - /** Flag indicating whether cache operation requires a previous value. */ - private boolean retVal; - - /** {@code True} if first lock request for lock operation sent from client node. */ - private boolean firstClientReq; - /** * Empty constructor required for {@link Externalizable}. */ @@ -152,14 +133,20 @@ public GridNearLockRequestV2( assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; this.topVer = topVer; - this.implicitTx = implicitTx; - this.implicitSingleTx = implicitSingleTx; - this.syncCommit = syncCommit; + if (implicitTx) + flags |= 1; + if (implicitSingleTx) + flags |= (1 << 1); + if (syncCommit) + flags |= (1 << 2); + if (retVal) + flags |= (1 << 3); + if (firstClientReq) + flags |= (1 << 4); + this.subjId = subjId; this.taskNameHash = taskNameHash; this.accessTtl = accessTtl; - this.retVal = retVal; - this.firstClientReq = firstClientReq; dhtVers = new GridCacheVersion[keyCnt]; } @@ -168,7 +155,7 @@ public GridNearLockRequestV2( * @return {@code True} if first lock request for lock operation sent from client node. */ public boolean firstClientRequest() { - return firstClientReq; + return (flags & (1 << 4)) != 0; } /** @@ -196,21 +183,21 @@ public int taskNameHash() { * @return Implicit transaction flag. */ public boolean implicitTx() { - return implicitTx; + return (flags & 1) != 0; } /** * @return Implicit-transaction-with-one-key flag. */ public boolean implicitSingleTx() { - return implicitSingleTx; + return (flags & (1 << 1)) != 0; } /** * @return Sync commit flag. */ public boolean syncCommit() { - return syncCommit; + return (flags & (1 << 2)) != 0; } /** @@ -252,21 +239,24 @@ public IgniteUuid oldVersionMiniId() { * @param hasTransforms {@code True} if originating transaction has transform entries. */ public void hasTransforms(boolean hasTransforms) { - this.hasTransforms = hasTransforms; + if (hasTransforms) + flags |= (1 << 5); + else + flags &= ~(1 << 5); } /** * @return {@code True} if originating transaction has transform entries. */ public boolean hasTransforms() { - return hasTransforms; + return (flags & (1 << 5)) != 0; } /** * @return Need return value flag. */ public boolean needReturnValue() { - return retVal; + return (flags & (1 << 3)) != 0; } /** @@ -367,66 +357,30 @@ public long accessTtl() { writer.incrementState(); case 23: - if (!writer.writeBoolean("firstClientReq", firstClientReq)) + if (!writer.writeByte("flags", flags)) return false; writer.incrementState(); case 24: - if (!writer.writeBoolean("hasTransforms", hasTransforms)) - return false; - - writer.incrementState(); - - case 25: - if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) - return false; - - writer.incrementState(); - - case 26: - if (!writer.writeBoolean("implicitTx", implicitTx)) - return false; - - writer.incrementState(); - - case 27: if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); - case 28: - if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) - return false; - - writer.incrementState(); - - case 29: - if (!writer.writeBoolean("retVal", retVal)) - return false; - - writer.incrementState(); - - case 30: + case 25: if (!writer.writeUuid("subjId", subjId)) return false; writer.incrementState(); - case 31: - if (!writer.writeBoolean("syncCommit", syncCommit)) - return false; - - writer.incrementState(); - - case 32: + case 26: if (!writer.writeInt("taskNameHash", taskNameHash)) return false; writer.incrementState(); - case 33: + case 27: if (!writer.writeMessage("topVer", topVer)) return false; @@ -473,7 +427,7 @@ public long accessTtl() { reader.incrementState(); case 23: - firstClientReq = reader.readBoolean("firstClientReq"); + flags = reader.readByte("flags"); if (!reader.isLastRead()) return false; @@ -481,30 +435,6 @@ public long accessTtl() { reader.incrementState(); case 24: - hasTransforms = reader.readBoolean("hasTransforms"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 25: - implicitSingleTx = reader.readBoolean("implicitSingleTx"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 26: - implicitTx = reader.readBoolean("implicitTx"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 27: miniId = reader.readInt("miniId"); if (!reader.isLastRead()) @@ -512,23 +442,7 @@ public long accessTtl() { reader.incrementState(); - case 28: - onePhaseCommit = reader.readBoolean("onePhaseCommit"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 29: - retVal = reader.readBoolean("retVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 30: + case 25: subjId = reader.readUuid("subjId"); if (!reader.isLastRead()) @@ -536,15 +450,7 @@ public long accessTtl() { reader.incrementState(); - case 31: - syncCommit = reader.readBoolean("syncCommit"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 32: + case 26: taskNameHash = reader.readInt("taskNameHash"); if (!reader.isLastRead()) @@ -552,7 +458,7 @@ public long accessTtl() { reader.incrementState(); - case 33: + case 27: topVer = reader.readMessage("topVer"); if (!reader.isLastRead()) @@ -572,7 +478,7 @@ public long accessTtl() { /** {@inheritDoc} */ @Override public byte fieldsCount() { - return 34; + return 28; } /** {@inheritDoc} */ From 9be6cdb5dd7fb407543c8e3b04897300c54d68f9 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 19 Feb 2016 13:59:21 +0300 Subject: [PATCH 31/34] ignite-2654 : minors --- .../processors/cache/GridCacheIoManager.java | 2 +- .../dht/GridDhtTransactionalCacheAdapter.java | 18 ++++-------------- .../colocated/GridDhtColocatedLockFuture.java | 6 ++---- .../distributed/near/GridNearLockFuture.java | 7 ++----- .../distributed/near/GridNearLockRequest.java | 6 ++++++ .../near/GridNearLockRequestV1.java | 12 ++++++++---- .../near/GridNearLockRequestV2.java | 4 +--- 7 files changed, 24 insertions(+), 31 deletions(-) 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 6599ecc725b7f..124088676de53 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 @@ -490,7 +490,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + req.oldVersionMiniId(), false, 0, req.classError(), 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 92c3ee1be2a6e..bf32895472e0d 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 @@ -878,12 +878,7 @@ public IgniteInternalFuture lockAllAsync( return new GridFinishedFuture<>(res); } - IgniteUuid miniId; - - if (req instanceof GridNearLockRequestV1) - miniId = ((GridNearLockRequestV1)req).miniId(); - else - miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); + IgniteUuid miniId = req.oldVersionMiniId(); tx = new GridDhtTxLocal( ctx.shared(), @@ -1058,12 +1053,7 @@ private GridNearLockResponse sendClientLockRemapResponse(ClusterNode nearNode, AffinityTopologyVersion topVer) { assert topVer != null; - IgniteUuid miniId; - - if (req instanceof GridNearLockRequestV1) - miniId = ((GridNearLockRequestV1)req).miniId(); - else - miniId = ((GridNearLockRequestV2)req).oldVersionMiniId(); + IgniteUuid miniId = req.oldVersionMiniId(); GridNearLockResponseV1 res = new GridNearLockResponseV1( ctx.cacheId(), @@ -1126,7 +1116,7 @@ private GridNearLockResponse createLockReply( res = new GridNearLockResponseV1(ctx.cacheId(), req.version(), req.futureId(), - ((GridNearLockRequestV1)req).miniId(), + req.oldVersionMiniId(), tx != null && tx.onePhaseCommit(), entries.size(), err, @@ -1250,7 +1240,7 @@ private GridNearLockResponse createLockReply( res = new GridNearLockResponseV1(ctx.cacheId(), req.version(), req.futureId(), - ((GridNearLockRequestV1)req).miniId(), + req.oldVersionMiniId(), false, entries.size(), e, 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 be9516bd587ee..515c590dd6616 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 @@ -46,6 +46,7 @@ import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockFuture; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockMapping; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; @@ -1031,10 +1032,7 @@ private void proceedMapping0() else { final MiniFuture fut = new MiniFuture(node, mappedKeys); - if (req instanceof GridNearLockRequestV1) - ((GridNearLockRequestV1)req).miniId(new IgniteUuid(GridNearLockRequestV2.DUMMY_UUID, fut.futureId())); - else - ((GridNearLockRequestV2)req).miniId(fut.futureId()); + req.miniId(fut.futureId()); add(fut); // Append new future. 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 599f9ea907906..ecc75110295ec 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 @@ -84,7 +84,7 @@ public final class GridNearLockFuture extends GridFutureAdapter implements GridCacheMvccFuture { - private static final UUID DUMMY_UUID = new UUID(0L, 0L); + public static final UUID DUMMY_UUID = new UUID(0L, 0L); /** */ private static final long serialVersionUID = 0L; @@ -1366,10 +1366,7 @@ private void proceedMapping0() sent.put(miniId, map); } - if (req instanceof GridNearLockRequestV2) - ((GridNearLockRequestV2)req).miniId(miniId); - else - ((GridNearLockRequestV1)req).miniId(new IgniteUuid(DUMMY_UUID, miniId)); + req.miniId(miniId); if (node.isLocal()) { if (log.isDebugEnabled()) { 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 0de4d126757e3..59ab746e4cd3b 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 @@ -79,4 +79,10 @@ void addKeyBytes( long messageId(); boolean returnValue(int idx); + + int miniId(); + + void miniId(int miniId); + + IgniteUuid oldVersionMiniId(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java index 14046f56dd03a..e305450cacf90 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java @@ -250,15 +250,19 @@ public GridNearLockRequestV1( /** * @return Mini future ID. */ - public IgniteUuid miniId() { - return miniId; + public int miniId() { + return (int) miniId.localId(); } /** * @param miniId Mini future Id. */ - public void miniId(IgniteUuid miniId) { - this.miniId = miniId; + public void miniId(int miniId) { + this.miniId = new IgniteUuid(GridNearLockFuture.DUMMY_UUID, miniId); + } + + public IgniteUuid oldVersionMiniId() { + return miniId; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java index 4ddd4534afede..c6c36b5b3131f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java @@ -27,8 +27,6 @@ public class GridNearLockRequestV2 extends GridDistributedLockRequest implements /** */ private static final long serialVersionUID = 0L; - public static final UUID DUMMY_UUID = new UUID(0, 0); - /** Topology version. */ private AffinityTopologyVersion topVer; @@ -232,7 +230,7 @@ public void miniId(int miniId) { } public IgniteUuid oldVersionMiniId() { - return new IgniteUuid(DUMMY_UUID, miniId); + return new IgniteUuid(GridNearLockFuture.DUMMY_UUID, miniId); } /** From 90fce7b9ec5c5226451cf592a9634fc66a2c9fcc Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Fri, 19 Feb 2016 16:25:46 +0300 Subject: [PATCH 32/34] ignite-2523: Merge. --- .../GridDhtAtomicMultipleUpdateRequest.java | 36 ++++++++++++++++--- .../GridDhtAtomicSingleUpdateRequest.java | 25 +++++++++++-- .../atomic/GridDhtAtomicUpdateRequest.java | 3 +- .../GridNearAtomicMultipleUpdateRequest.java | 12 +++++++ .../GridNearAtomicSingleUpdateRequest.java | 13 ++++++- .../atomic/GridNearAtomicUpdateRequest.java | 7 ++++ 6 files changed, 88 insertions(+), 8 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java index 40d68faaa04ab..8a0cc69003c68 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java @@ -251,12 +251,18 @@ public GridDhtAtomicMultipleUpdateRequest( boolean addPrevVal, int partId, @Nullable CacheObject prevVal, - @Nullable Long updateIdx) { + @Nullable Long updateCntr, + boolean storeLocPrevVal) { keys.add(key); partIds.add(partId); - locPrevVals.add(prevVal); + if (storeLocPrevVal) { + if (locPrevVals == null) + locPrevVals = new ArrayList<>(); + + locPrevVals.add(prevVal); + } if (forceTransformBackups) { assert entryProcessor != null; @@ -273,11 +279,11 @@ public GridDhtAtomicMultipleUpdateRequest( prevVals.add(prevVal); } - if (updateIdx != null) { + if (updateCntr != null) { if (updateCntrs == null) updateCntrs = new GridLongList(); - updateCntrs.add(updateIdx); + updateCntrs.add(updateCntr); } // In case there is no conflict, do not create the list. @@ -521,6 +527,8 @@ else if (conflictVers != null) * @return Value. */ @Override @Nullable public CacheObject localPreviousValue(int idx) { + assert locPrevVals != null; + return locPrevVals.get(idx); } @@ -1048,6 +1056,26 @@ else if (conflictVers != null) return reader.afterMessageRead(GridDhtAtomicMultipleUpdateRequest.class); } + /** {@inheritDoc} */ + @Override public void onAckReceived() { + cleanup(); + } + + /** + * Cleanup values not needed after message was sent. + */ + private void cleanup() { + nearVals = null; + prevVals = null; + + // Do not keep values if they are not needed for continuous query notification. + if (locPrevVals == null) { + keys = null; + vals = null; + locPrevVals = null; + } + } + /** {@inheritDoc} */ @Override public byte directType() { return 38; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java index 0c0dd191bd1e8..b78cc4a8fcf07 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java @@ -216,12 +216,13 @@ public GridDhtAtomicSingleUpdateRequest( boolean addPrevVal, int partId, @Nullable CacheObject prevVal, - @Nullable Long updateIdx) { + @Nullable Long updateIdx, + boolean storeLocPrevVal) { this.key = key; this.partId = partId; - this.locPrevVal = prevVal; + this.locPrevVal = storeLocPrevVal ? prevVal : null; if (forceTransformBackups) { assert entryProcessor != null; @@ -939,6 +940,26 @@ public GridDhtAtomicSingleUpdateRequest( return reader.afterMessageRead(GridDhtAtomicSingleUpdateRequest.class); } + /** {@inheritDoc} */ + @Override public void onAckReceived() { + cleanup(); + } + + /** + * Cleanup values not needed after message was sent. + */ + private void cleanup() { + nearVal = null; + prevVal = null; + + // Do not keep values if they are not needed for continuous query notification. + if (locPrevVal == null) { + key = null; + val = null; + locPrevVal = null; + } + } + /** {@inheritDoc} */ @Override public byte directType() { return -25; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java index 0ab67a686ebaf..280b98e144955 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java @@ -47,7 +47,8 @@ void addWriteValue(KeyCacheObject key, boolean addPrevVal, int partId, @Nullable CacheObject prevVal, - @Nullable Long updateIdx); + @Nullable Long updateIdx, + boolean storeLocPrevVal); void addNearWriteValue(KeyCacheObject key, @Nullable CacheObject val, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java index 650d350f76a84..86de2e2c63444 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java @@ -958,6 +958,18 @@ else if (conflictVers != null) return reader.afterMessageRead(GridNearAtomicMultipleUpdateRequest.class); } + /** {@inheritDoc} */ + @Override public void cleanup(boolean clearKeys) { + vals = null; + entryProcessors = null; + entryProcessorsBytes = null; + invokeArgs = null; + invokeArgsBytes = null; + + if (clearKeys) + keys = null; + } + /** {@inheritDoc} */ @Override public byte directType() { return 40; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 1e981afd9a212..94a586d90cea6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -243,7 +243,7 @@ public GridNearAtomicSingleUpdateRequest( if (op == TRANSFORM) { assert val instanceof EntryProcessor : val; - entryProc = (EntryProcessor) val; + entryProc = (EntryProcessor)val; } assert val != null || op == DELETE; @@ -869,6 +869,17 @@ else if (val != null) { return reader.afterMessageRead(GridNearAtomicSingleUpdateRequest.class); } + @Override public void cleanup(boolean clearKeys) { + val = null; + entryProc = null; + entryProcBytes = null; + invokeArgs = null; + invokeArgsBytes = null; + + if (clearKeys) + key = null; + } + /** {@inheritDoc} */ @Override public byte directType() { return -23; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 960add7eb0ba3..bf935593469de 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -196,4 +196,11 @@ public interface GridNearAtomicUpdateRequest { * @return Response. */ @Nullable public GridNearAtomicUpdateResponse response(); + + /** + * Cleanup values. + * + * @param clearKeys If {@code true} clears keys. + */ + void cleanup(boolean clearKeys); } From d65dd7a52b1f511b08d3e2de25a61eaca484a275 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Sat, 20 Feb 2016 10:52:43 +0300 Subject: [PATCH 33/34] TX prepare request/response optimizations. --- .../communication/GridIoMessageFactory.java | 48 +- .../cache/GridCacheAtomicFuture.java | 6 + .../processors/cache/GridCacheIoManager.java | 62 +- .../processors/cache/GridCacheMessage.java | 49 - .../GridDistributedLockRequest.java | 7 +- .../distributed/dht/GridDhtLockFuture.java | 15 +- .../distributed/dht/GridDhtLockRequest.java | 12 +- .../distributed/dht/GridDhtLockResponse.java | 16 +- .../dht/GridDhtTransactionalCacheAdapter.java | 89 +- .../cache/distributed/dht/GridDhtTxLocal.java | 13 +- .../dht/GridDhtTxPrepareFuture.java | 8 +- .../dht/atomic/GridDhtAtomicCache.java | 82 +- .../GridDhtAtomicMultipleUpdateRequest.java | 1093 ----------------- .../GridDhtAtomicMultipleUpdateResponse.java | 297 ----- .../GridDhtAtomicSingleUpdateRequest.java | 977 --------------- .../GridDhtAtomicSingleUpdateResponse.java | 287 ----- .../dht/atomic/GridDhtAtomicUpdateFuture.java | 99 +- .../atomic/GridDhtAtomicUpdateRequest.java | 1087 +++++++++++++++- .../atomic/GridDhtAtomicUpdateResponse.java | 300 ++++- .../GridNearAtomicMultipleUpdateRequest.java | 988 --------------- .../GridNearAtomicMultipleUpdateResponse.java | 640 ---------- .../GridNearAtomicSingleUpdateRequest.java | 898 -------------- .../GridNearAtomicSingleUpdateResponse.java | 614 --------- .../atomic/GridNearAtomicUpdateFuture.java | 192 +-- .../atomic/GridNearAtomicUpdateRequest.java | 930 +++++++++++++- .../atomic/GridNearAtomicUpdateResponse.java | 616 +++++++++- .../dht/colocated/GridDhtColocatedCache.java | 8 +- .../colocated/GridDhtColocatedLockFuture.java | 34 +- .../distributed/near/GridNearAtomicCache.java | 1 - .../distributed/near/GridNearLockFuture.java | 874 ++++++------- .../distributed/near/GridNearLockRequest.java | 594 +-------- .../near/GridNearLockRequestV1.java | 600 +++++++++ .../near/GridNearLockRequestV2.java | 487 ++++++++ .../near/GridNearLockResponse.java | 322 +---- .../near/GridNearLockResponseV1.java | 330 +++++ .../near/GridNearLockResponseV2.java | 310 +++++ ...OptimisticSerializableTxPrepareFuture.java | 19 +- .../GridNearOptimisticTxPrepareFuture.java | 19 +- .../GridNearPessimisticTxPrepareFuture.java | 16 +- .../near/GridNearTransactionalCache.java | 11 +- .../distributed/near/GridNearTxLocal.java | 2 +- .../near/GridNearTxPrepareRequest.java | 10 +- .../near/GridNearTxPrepareResponse.java | 11 +- .../IgniteClientReconnectAtomicsTest.java | 10 +- .../IgniteClientReconnectCacheTest.java | 8 +- .../IgniteClientReconnectCollectionsTest.java | 6 +- .../GridCacheAtomicMessageCountSelfTest.java | 48 +- .../IgniteCacheAtomicStopBusySelfTest.java | 15 +- .../IgniteCacheNearLockValueSelfTest.java | 8 +- .../IgniteTxReentryAbstractSelfTest.java | 4 +- ...teCacheClientNodeChangingTopologyTest.java | 104 +- ...tomicInvalidPartitionHandlingSelfTest.java | 7 +- 52 files changed, 5339 insertions(+), 7944 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.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 23661047c911f..9ac507a97f554 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 @@ -66,14 +66,10 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtUnlockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicDeferredUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +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.GridDhtPartitionDemandMessage; @@ -86,8 +82,10 @@ import org.apache.ignite.internal.processors.cache.distributed.near.CacheVersionedValue; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishRequest; @@ -356,22 +354,22 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 38: - msg = new GridDhtAtomicMultipleUpdateRequest(); + msg = new GridDhtAtomicUpdateRequest(); break; case 39: - msg = new GridDhtAtomicMultipleUpdateResponse(); + msg = new GridDhtAtomicUpdateResponse(); break; case 40: - msg = new GridNearAtomicMultipleUpdateRequest(); + msg = new GridNearAtomicUpdateRequest(); break; case 41: - msg = new GridNearAtomicMultipleUpdateResponse(); + msg = new GridNearAtomicUpdateResponse(); break; @@ -421,12 +419,12 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; case 51: - msg = new GridNearLockRequest(); + msg = new GridNearLockRequestV1(); break; case 52: - msg = new GridNearLockResponse(); + msg = new GridNearLockResponseV1(); break; @@ -730,23 +728,13 @@ public GridIoMessageFactory(MessageFactory[] ext) { break; - case -23: - msg = new GridNearAtomicSingleUpdateRequest(); + case 125: + msg = new GridNearLockRequestV2(); break; - case -24: - msg = new GridNearAtomicSingleUpdateResponse(); - - break; - - case -25: - msg = new GridDhtAtomicSingleUpdateRequest(); - - break; - - case -26: - msg = new GridDhtAtomicSingleUpdateResponse(); + case 126: + msg = new GridNearLockResponseV2(); break; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java index be24191d4cdd5..359909ed0d400 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.cache; +import java.util.Collection; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -37,4 +38,9 @@ public interface GridCacheAtomicFuture extends GridCacheFuture { * @return Future or {@code null} if no need to wait. */ public IgniteInternalFuture completeFuture(AffinityTopologyVersion topVer); + + /** + * @return Future keys. + */ + public Collection keys(); } \ No newline at end of file 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 a4ad5004b350c..124088676de53 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 @@ -42,22 +42,16 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicSingleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; +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.near.GridNearGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest; @@ -402,30 +396,22 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC case 38: { GridDhtAtomicUpdateRequest req = (GridDhtAtomicUpdateRequest)msg; - GridDhtAtomicUpdateResponse res; - - if (req instanceof GridDhtAtomicSingleUpdateRequest) - res = new GridDhtAtomicSingleUpdateResponse( - ctx.cacheId(), - req.futureVersion(), - ctx.deploymentEnabled()); - else - res = new GridDhtAtomicMultipleUpdateResponse( - ctx.cacheId(), - req.futureVersion(), - ctx.deploymentEnabled()); + GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse( + ctx.cacheId(), + req.futureVersion(), + ctx.deploymentEnabled()); res.onError(req.classError()); - sendResponseOnFailedMessage(nodeId, (GridCacheMessage) res, cctx, ctx.ioPolicy()); + sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy()); } break; case 40: { - GridNearAtomicMultipleUpdateRequest req = (GridNearAtomicMultipleUpdateRequest)msg; + GridNearAtomicUpdateRequest req = (GridNearAtomicUpdateRequest)msg; - GridNearAtomicMultipleUpdateResponse res = new GridNearAtomicMultipleUpdateResponse( + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse( ctx.cacheId(), nodeId, req.futureVersion(), @@ -456,7 +442,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 45: { - processMessage(nodeId, msg, c);// Will be handled by Rebalance Demander. + processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander. } break; @@ -498,13 +484,13 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 51: { - GridNearLockRequest req = (GridNearLockRequest)msg; + GridNearLockRequestV1 req = (GridNearLockRequestV1)msg; - GridNearLockResponse res = new GridNearLockResponse( + GridNearLockResponseV1 res = new GridNearLockResponseV1( ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + req.oldVersionMiniId(), false, 0, req.classError(), @@ -557,7 +543,7 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; case 114: { - processMessage(nodeId, msg, c);// Will be handled by Rebalance Demander. + processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander. } break; @@ -600,22 +586,6 @@ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInC break; - case -23: { - GridNearAtomicSingleUpdateRequest req = (GridNearAtomicSingleUpdateRequest)msg; - - GridNearAtomicSingleUpdateResponse res = new GridNearAtomicSingleUpdateResponse( - ctx.cacheId(), - nodeId, - req.futureVersion(), - ctx.deploymentEnabled()); - - res.error(req.classError()); - - sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy()); - } - - break; - default: throw new IgniteCheckedException("Failed to send response to node. Unsupported direct type [message=" + msg + "]", msg.classError()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java index 7e3887fbb224d..b6f5adf9afa9d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java @@ -462,24 +462,6 @@ protected final void unmarshalTx(Iterable txEntries, return args; } - /** - * @param obj Object to marshal. - * @param ctx Context. - * @return Marshalled collection. - * @throws IgniteCheckedException If failed. - */ - @Nullable protected byte[] marshal(@Nullable Object obj, GridCacheContext ctx) throws IgniteCheckedException { - assert ctx != null; - - if (obj == null) - return null; - - if (addDepInfo) - prepareObject(obj, ctx); - - return CU.marshal(ctx, obj); - } - /** * @param col Collection to marshal. * @param ctx Context. @@ -556,19 +538,6 @@ protected final void prepareMarshalCacheObjects(@Nullable Collection T unmarshal(@Nullable byte[] bytes, GridCacheSharedContext ctx, ClassLoader ldr) - throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; - - if (bytes == null) - return null; - - return ctx.marshaller().unmarshal(bytes, ldr); - } - /** * @param byteCol Collection to unmarshal. * @param ctx Context. 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 5d07b6faad974..f569346929d12 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 @@ -21,6 +21,7 @@ import java.util.ArrayList; 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; @@ -232,7 +233,7 @@ public boolean[] returnFlags() { * * @param skipStore Skip store flag. */ - private void skipStore(boolean skipStore){ + private void skipStore(boolean skipStore) { flags = skipStore ? (byte)(flags | SKIP_STORE_FLAG_MASK) : (byte)(flags & ~SKIP_STORE_FLAG_MASK); } @@ -301,6 +302,10 @@ public List keys() { return keys; } + public void keys(List keys) { + this.keys = keys; + } + /** * @return Max lock wait time. */ 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 07755e0004fb3..2f3bf13a2ec46 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 @@ -27,6 +27,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; @@ -164,6 +165,8 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture /** Keep binary. */ private final boolean keepBinary; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Cache context. * @param nearNodeId Near node ID. @@ -544,14 +547,14 @@ void onResult(UUID nodeId, GridDhtLockResponse res) { * @return Mini future. */ @SuppressWarnings("ForLoopReplaceableByForEach") - private MiniFuture miniFuture(IgniteUuid miniId) { + private MiniFuture miniFuture(int 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.miniId() == miniId) { if (!mini.isDone()) return mini; else @@ -860,7 +863,7 @@ private void map(Iterable entries) { inTx() ? tx.nearXidVersion() : null, threadId, futId, - fut.futureId(), + fut.miniId(), lockVer, topVer, inTx(), @@ -1095,7 +1098,7 @@ private class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** Node. */ @GridToStringExclude @@ -1119,8 +1122,8 @@ private class MiniFuture extends GridFutureAdapter { /** * @return Future ID. */ - IgniteUuid futureId() { - return futId; + int miniId() { + return miniId; } /** 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 50167d84c5db9..dbbe83716a104 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 @@ -62,7 +62,7 @@ public class GridDhtLockRequest extends GridDistributedLockRequest { private BitSet invalidateEntries; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** Owner mapped version, if any. */ @GridToStringInclude @@ -129,7 +129,7 @@ public GridDhtLockRequest( GridCacheVersion nearXidVer, long threadId, IgniteUuid futId, - IgniteUuid miniId, + int miniId, GridCacheVersion lockVer, @NotNull AffinityTopologyVersion topVer, boolean isInTx, @@ -169,8 +169,6 @@ public GridDhtLockRequest( nearKeys = nearCnt == 0 ? Collections.emptyList() : new ArrayList(nearCnt); invalidateEntries = new BitSet(dhtCnt == 0 ? nearCnt : dhtCnt); - assert miniId != null; - this.miniId = miniId; this.subjId = subjId; this.taskNameHash = taskNameHash; @@ -294,7 +292,7 @@ public boolean invalidateNearEntry(int idx) { /** * @return Mini ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -372,7 +370,7 @@ public long accessTtl() { writer.incrementState(); case 22: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -452,7 +450,7 @@ public long accessTtl() { reader.incrementState(); case 22: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java index 1e92b54fc59f1..f0f026dd16cc6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java @@ -52,7 +52,7 @@ public class GridDhtLockResponse extends GridDistributedLockResponse { private Collection nearEvicted; /** Mini ID. */ - private IgniteUuid miniId; + private int miniId; /** Invalid partitions. */ @GridToStringInclude @@ -77,12 +77,10 @@ public GridDhtLockResponse() { * @param cnt Key count. * @param addDepInfo Deployment info. */ - public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId, int cnt, + public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, int miniId, int cnt, boolean addDepInfo) { super(cacheId, lockVer, futId, cnt, addDepInfo); - assert miniId != null; - this.miniId = miniId; } @@ -93,12 +91,10 @@ public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid fut * @param err Error. * @param addDepInfo */ - public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId, + public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, int miniId, Throwable err, boolean addDepInfo) { super(cacheId, lockVer, futId, err, addDepInfo); - assert miniId != null; - this.miniId = miniId; } @@ -119,7 +115,7 @@ public void nearEvicted(Collection nearEvicted) { /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -211,7 +207,7 @@ public Collection preloadEntries() { writer.incrementState(); case 11: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -253,7 +249,7 @@ public Collection preloadEntries() { reader.incrementState(); case 11: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; 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 ae24ed1a84296..5f202e12bc10b 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 @@ -26,6 +26,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.UUID; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -40,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -48,8 +50,12 @@ import org.apache.ignite.internal.processors.cache.distributed.GridDistributedUnlockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote; @@ -73,6 +79,7 @@ import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.transactions.TransactionIsolation; import org.jetbrains.annotations.Nullable; @@ -133,8 +140,14 @@ protected GridDhtTransactionalCacheAdapter(GridCacheContext ctx, GridCache } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockRequestV2.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockRequestV2 req) { + processNearLockRequest(nodeId, req); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridNearLockRequestV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockRequestV1 req) { processNearLockRequest(nodeId, req); } }); @@ -865,12 +878,14 @@ public IgniteInternalFuture lockAllAsync( return new GridFinishedFuture<>(res); } + int miniId = req.miniId(); + tx = new GridDhtTxLocal( ctx.shared(), nearNode.id(), req.version(), req.futureId(), - req.miniId(), + miniId, req.threadId(), req.implicitTx(), req.implicitSingleTx(), @@ -952,7 +967,8 @@ public IgniteInternalFuture lockAllAsync( return t.commitAsync().chain( new C1, GridNearLockResponse>() { - @Override public GridNearLockResponse apply(IgniteInternalFuture f) { + @Override public GridNearLockResponse apply( + IgniteInternalFuture f) { try { // Check for error. f.get(); @@ -970,7 +986,7 @@ public IgniteInternalFuture lockAllAsync( else { sendLockReply(nearNode, t, req, resp); - return new GridFinishedFuture<>(resp); + return new GridFinishedFuture(resp); } } } @@ -1037,11 +1053,13 @@ private GridNearLockResponse sendClientLockRemapResponse(ClusterNode nearNode, AffinityTopologyVersion topVer) { assert topVer != null; - GridNearLockResponse res = new GridNearLockResponse( + IgniteUuid miniId = req.oldVersionMiniId(); + + GridNearLockResponseV1 res = new GridNearLockResponseV1( ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + miniId, false, 0, null, @@ -1082,18 +1100,30 @@ private GridNearLockResponse createLockReply( assert mappedVer != null; assert tx == null || tx.xidVersion().equals(mappedVer); - try { - // Send reply back to originating near node. - GridNearLockResponse res = new GridNearLockResponse(ctx.cacheId(), + GridNearLockResponse res; + + if (req instanceof GridNearLockRequestV2) + res = new GridNearLockResponseV2(ctx.cacheId(), req.version(), req.futureId(), - req.miniId(), + ((GridNearLockRequestV2)req).miniId(), + tx != null && tx.onePhaseCommit(), + entries.size(), + err, + null, + ctx.deploymentEnabled()); + else + res = new GridNearLockResponseV1(ctx.cacheId(), + req.version(), + req.futureId(), + req.oldVersionMiniId(), tx != null && tx.onePhaseCommit(), entries.size(), err, null, ctx.deploymentEnabled()); + try { if (err == null) { res.pending(localDhtPendingVersions(entries, mappedVer)); @@ -1105,7 +1135,7 @@ private GridNearLockResponse createLockReply( int i = 0; - for (ListIterator it = entries.listIterator(); it.hasNext();) { + for (ListIterator it = entries.listIterator(); it.hasNext(); ) { GridCacheEntryEx e = it.next(); assert e != null; @@ -1196,15 +1226,28 @@ private GridNearLockResponse createLockReply( U.error(log, "Failed to get value for lock reply message for node [node=" + U.toShortString(nearNode) + ", req=" + req + ']', e); - return new GridNearLockResponse(ctx.cacheId(), - req.version(), - req.futureId(), - req.miniId(), - false, - entries.size(), - e, - null, - ctx.deploymentEnabled()); + if (req instanceof GridNearLockRequestV2) + res = new GridNearLockResponseV2(ctx.cacheId(), + req.version(), + req.futureId(), + ((GridNearLockRequestV2)req).miniId(), + false, + entries.size(), + e, + null, + ctx.deploymentEnabled()); + else + res = new GridNearLockResponseV1(ctx.cacheId(), + req.version(), + req.futureId(), + req.oldVersionMiniId(), + false, + entries.size(), + e, + null, + ctx.deploymentEnabled()); + + return res; } } @@ -1231,7 +1274,7 @@ private void sendLockReply( try { // Don't send reply message to this node or if lock was cancelled. if (!nearNode.id().equals(ctx.nodeId()) && !X.hasCause(err, GridDistributedLockCancelledException.class)) - ctx.io().send(nearNode, res, ctx.ioPolicy()); + ctx.io().send(nearNode, (GridCacheMessage)res, ctx.ioPolicy()); } catch (IgniteCheckedException e) { U.error(log, "Failed to send lock reply to originating node (will rollback transaction) [node=" + @@ -1402,7 +1445,7 @@ private void map(UUID nodeId, * @param nodes Nodes. * @param map Map. */ - @SuppressWarnings( {"MismatchedQueryAndUpdateOfCollection"}) + @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) private void map(GridCacheEntryEx entry, @Nullable Iterable nodes, Map> map) { 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 ebf10029898cc..9ffb52b0e1052 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 @@ -73,7 +73,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa private IgniteUuid nearFutId; /** Near future ID. */ - private IgniteUuid nearMiniId; + private int nearMiniId; /** Near future ID. */ private IgniteUuid nearFinFutId; @@ -121,7 +121,7 @@ public GridDhtTxLocal( UUID nearNodeId, GridCacheVersion nearXidVer, IgniteUuid nearFutId, - IgniteUuid nearMiniId, + int nearMiniId, long nearThreadId, boolean implicit, boolean implicitSingle, @@ -160,7 +160,6 @@ public GridDhtTxLocal( assert cctx != null; assert nearNodeId != null; assert nearFutId != null; - assert nearMiniId != null; assert nearXidVer != null; this.nearNodeId = nearNodeId; @@ -383,7 +382,7 @@ public IgniteInternalFuture prepareAsync( @Nullable Collection writes, Map verMap, long msgId, - IgniteUuid nearMiniId, + int nearMiniId, Map> txNodes, boolean last ) { @@ -403,14 +402,14 @@ public IgniteInternalFuture prepareAsync( needReturnValue()))) { GridDhtTxPrepareFuture f = prepFut; - assert f.nearMiniId().equals(nearMiniId) : "Wrong near mini id on existing future " + + assert f.nearMiniId() == nearMiniId : "Wrong near mini id on existing future " + "[futMiniId=" + f.nearMiniId() + ", miniId=" + nearMiniId + ", fut=" + f + ']'; return chainOnePhasePrepare(f); } } else { - assert fut.nearMiniId().equals(nearMiniId) : "Wrong near mini id on existing future " + + assert fut.nearMiniId() == nearMiniId : "Wrong near mini id on existing future " + "[futMiniId=" + fut.nearMiniId() + ", miniId=" + nearMiniId + ", fut=" + fut + ']'; // Prepare was called explicitly. @@ -650,8 +649,6 @@ public IgniteInternalFuture prepareAsync( "Invalid state [nearFinFutId=" + nearFinFutId + ", isInvalidate=" + isInvalidate() + ", commit=" + commit + ", sysInvalidate=" + isSystemInvalidate() + ", state=" + state() + ']'; - assert nearMiniId != null; - return super.finish(commit); } 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 732c2982016da..eec846109c49a 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 @@ -171,7 +171,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture dhtVerMap; @@ -212,7 +212,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture dhtVerMap, boolean last, boolean retVal @@ -248,7 +248,7 @@ public GridDhtTxPrepareFuture( /** * @return Near mini future id. */ - public IgniteUuid nearMiniId() { + public int nearMiniId() { return nearMiniId; } @@ -757,7 +757,7 @@ private GridNearTxPrepareResponse createPrepareResponse(@Nullable Throwable prep GridNearTxPrepareResponse res = new GridNearTxPrepareResponse( tx.nearXidVersion(), tx.colocated() ? tx.xid() : tx.nearFutureId(), - nearMiniId == null ? tx.xid() : nearMiniId, + nearMiniId, tx.xidVersion(), tx.writeVersion(), ret, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 4faf91a584d1f..e908c05c39f98 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -55,7 +55,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheMapEntry; import org.apache.ignite.internal.processors.cache.GridCacheMapEntryFactory; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; import org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult; @@ -252,50 +251,26 @@ else if (res.error() != null) { } }); - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicMultipleUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicMultipleUpdateRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicUpdateRequest req) { processNearAtomicUpdateRequest(nodeId, req); } }); - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicSingleUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicSingleUpdateRequest req) { - processNearAtomicUpdateRequest(nodeId, req); - } - }); - - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicMultipleUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicMultipleUpdateResponse res) { - processNearAtomicUpdateResponse(nodeId, res); - } - }); - - ctx.io().addHandler(ctx.cacheId(), GridNearAtomicSingleUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearAtomicSingleUpdateResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearAtomicUpdateResponse res) { processNearAtomicUpdateResponse(nodeId, res); } }); - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicMultipleUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicMultipleUpdateRequest req) { - processDhtAtomicUpdateRequest(nodeId, req); - } - }); - - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicSingleUpdateRequest.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicSingleUpdateRequest req) { + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicUpdateRequest.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicUpdateRequest req) { processDhtAtomicUpdateRequest(nodeId, req); } }); - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicMultipleUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicMultipleUpdateResponse res) { - processDhtAtomicUpdateResponse(nodeId, res); - } - }); - - ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicSingleUpdateResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridDhtAtomicSingleUpdateResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridDhtAtomicUpdateResponse.class, new CI2() { + @Override public void apply(UUID nodeId, GridDhtAtomicUpdateResponse res) { processDhtAtomicUpdateResponse(nodeId, res); } }); @@ -887,8 +862,7 @@ protected IgniteInternalFuture asyncOp(final CO> TRANSFORM); return resFut.chain(new CX1>>, Map>>() { - @Override public Map> applyx( - IgniteInternalFuture>> fut) throws IgniteCheckedException { + @Override public Map> applyx(IgniteInternalFuture>> fut) throws IgniteCheckedException { Map resMap = (Map)fut.get(); return ctx.unwrapInvokeResult(resMap, keepBinary); @@ -1359,14 +1333,8 @@ public void updateAllAsyncInternal0( GridNearAtomicUpdateRequest req, CI2 completionCb ) { - GridNearAtomicUpdateResponse res; - - if (req instanceof GridNearAtomicSingleUpdateRequest) - res = new GridNearAtomicSingleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), - ctx.deploymentEnabled()); - else - res = new GridNearAtomicMultipleUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), - ctx.deploymentEnabled()); + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(), + ctx.deploymentEnabled()); List keys = req.keys(); @@ -1451,7 +1419,7 @@ public void updateAllAsyncInternal0( UpdateBatchResult updRes = updateWithBatch(node, hasNear, req, - (GridNearAtomicMultipleUpdateResponse)res, + res, locked, ver, dhtFut, @@ -1589,7 +1557,7 @@ private UpdateBatchResult updateWithBatch( ClusterNode node, boolean hasNear, GridNearAtomicUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res, + GridNearAtomicUpdateResponse res, List locked, GridCacheVersion ver, @Nullable GridDhtAtomicUpdateFuture dhtFut, @@ -1827,7 +1795,7 @@ else if (op == UPDATE) { if (intercept) { CacheObject old = entry.innerGet( - null, + null, /*read swap*/true, /*read through*/ctx.loadPreviousValue(), /*fail fast*/false, @@ -1842,7 +1810,7 @@ else if (op == UPDATE) { req.keepBinary()); Object val = ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(), - old, req.keepBinary()), + old, req.keepBinary()), updated.value(ctx.cacheObjectContext(), false)); if (val == null) @@ -2268,7 +2236,7 @@ else if (F.contains(readers, node.id())) // Reader became primary or backup. @Nullable GridDhtAtomicUpdateFuture dhtFut, CI2 completionCb, final GridNearAtomicUpdateRequest req, - final GridNearAtomicMultipleUpdateResponse res, + final GridNearAtomicUpdateResponse res, boolean replicate, UpdateBatchResult batchRes, String taskName, @@ -2659,7 +2627,7 @@ private void unlockEntries(Collection locked, AffinityTopolog * @return {@code True} if filter evaluation succeeded. */ private boolean checkFilter(GridCacheEntryEx entry, GridNearAtomicUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res) { + GridNearAtomicUpdateResponse res) { try { return ctx.isAllLocked(entry, req.filter()); } @@ -2825,14 +2793,8 @@ private void processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicUpdateReque GridCacheVersion ver = req.writeVersion(); // Always send update reply. - GridDhtAtomicUpdateResponse res; - - if (req instanceof GridDhtAtomicSingleUpdateRequest) - res = new GridDhtAtomicSingleUpdateResponse(ctx.cacheId(), req.futureVersion(), - ctx.deploymentEnabled()); - else - res = new GridDhtAtomicMultipleUpdateResponse(ctx.cacheId(), req.futureVersion(), - ctx.deploymentEnabled()); + GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.futureVersion(), + ctx.deploymentEnabled()); Boolean replicate = ctx.isDrEnabled(); @@ -2949,7 +2911,7 @@ private void processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicUpdateReque try { if (res.failedKeys() != null || res.nearEvicted() != null || req.writeSynchronizationMode() == FULL_SYNC) - ctx.io().send(nodeId, (GridCacheMessage) res, ctx.ioPolicy()); + ctx.io().send(nodeId, res, ctx.ioPolicy()); else { // No failed keys and sync mode is not FULL_SYNC, thus sending deferred response. sendDeferredUpdateResponse(nodeId, req.futureVersion()); @@ -3038,7 +3000,7 @@ private void processDhtAtomicDeferredUpdateResponse(UUID nodeId, GridDhtAtomicDe */ private void sendNearUpdateReply(UUID nodeId, GridNearAtomicUpdateResponse res) { try { - ctx.io().send(nodeId, (GridCacheMessage)res, ctx.ioPolicy()); + ctx.io().send(nodeId, res, ctx.ioPolicy()); } catch (ClusterTopologyCheckedException ignored) { U.warn(log, "Failed to send near update reply to node because it left grid: " + @@ -3280,7 +3242,7 @@ public boolean addResponse(GridCacheVersion ver) { respVers.add(ver); - if (respVers.sizex() > DEFERRED_UPDATE_RESPONSE_BUFFER_SIZE && guard.compareAndSet(false, true)) + if (respVers.sizex() > DEFERRED_UPDATE_RESPONSE_BUFFER_SIZE && guard.compareAndSet(false, true)) snd = true; } finally { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java deleted file mode 100644 index 8a0cc69003c68..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateRequest.java +++ /dev/null @@ -1,1093 +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.atomic; - -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import javax.cache.processor.EntryProcessor; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; -import org.apache.ignite.internal.GridDirectTransient; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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; -import org.apache.ignite.internal.util.GridLongList; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * Lite dht cache backup update request. - */ -public class GridDhtAtomicMultipleUpdateRequest extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateRequest { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID. */ - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Write version. */ - private GridCacheVersion writeVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List vals; - - /** Previous values. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List prevVals; - - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; - - /** TTLs. */ - private GridLongList ttls; - - /** Conflict expire time. */ - private GridLongList conflictExpireTimes; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Near cache keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearKeys; - - /** Values to update. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; - - /** Force transform backups flag. */ - private boolean forceTransformBackups; - - /** Entry processors. */ - @GridDirectTransient - private List> entryProcessors; - - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; - - /** Near entry processors. */ - @GridDirectTransient - private List> nearEntryProcessors; - - /** Near entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List nearEntryProcessorsBytes; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Partition. */ - private GridLongList updateCntrs; - - /** On response flag. Access should be synced on future. */ - @GridDirectTransient - private boolean onRes; - - /** */ - @GridDirectTransient - private List partIds; - - /** */ - @GridDirectTransient - private List locPrevVals; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicMultipleUpdateRequest() { - // No-op. - } - - /** - * Constructor. - * - * @param cacheId Cache ID. - * @param nodeId Node ID. - * @param futVer Future version. - * @param writeVer Write version for cache values. - * @param invokeArgs Optional arguments for entry processor. - * @param syncMode Cache write synchronization mode. - * @param topVer Topology version. - * @param forceTransformBackups Force transform backups flag. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicMultipleUpdateRequest( - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - GridCacheVersion writeVer, - CacheWriteSynchronizationMode syncMode, - @NotNull AffinityTopologyVersion topVer, - boolean forceTransformBackups, - UUID subjId, - int taskNameHash, - Object[] invokeArgs, - boolean addDepInfo, - boolean keepBinary - ) { - assert invokeArgs == null || forceTransformBackups; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.writeVer = writeVer; - this.syncMode = syncMode; - this.topVer = topVer; - this.forceTransformBackups = forceTransformBackups; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.invokeArgs = invokeArgs; - this.addDepInfo = addDepInfo; - this.keepBinary = keepBinary; - - keys = new ArrayList<>(); - partIds = new ArrayList<>(); - locPrevVals = new ArrayList<>(); - - if (forceTransformBackups) { - entryProcessors = new ArrayList<>(); - entryProcessorsBytes = new ArrayList<>(); - } - else - vals = new ArrayList<>(); - } - - /** - * @return Force transform backups flag. - */ - @Override public boolean forceTransformBackups() { - return forceTransformBackups; - } - - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param addPrevVal If {@code true} adds previous value. - * @param prevVal Previous value. - */ - @Override public void addWriteValue(KeyCacheObject key, - @Nullable CacheObject val, - EntryProcessor entryProcessor, - long ttl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - boolean addPrevVal, - int partId, - @Nullable CacheObject prevVal, - @Nullable Long updateCntr, - boolean storeLocPrevVal) { - keys.add(key); - - partIds.add(partId); - - if (storeLocPrevVal) { - if (locPrevVals == null) - locPrevVals = new ArrayList<>(); - - locPrevVals.add(prevVal); - } - - if (forceTransformBackups) { - assert entryProcessor != null; - - entryProcessors.add(entryProcessor); - } - else - vals.add(val); - - if (addPrevVal) { - if (prevVals == null) - prevVals = new ArrayList<>(); - - prevVals.add(prevVal); - } - - if (updateCntr != null) { - if (updateCntrs == null) - updateCntrs = new GridLongList(); - - updateCntrs.add(updateCntr); - } - - // In case there is no conflict, do not create the list. - if (conflictVer != null) { - if (conflictVers == null) { - conflictVers = new ArrayList<>(); - - for (int i = 0; i < keys.size() - 1; i++) - conflictVers.add(null); - } - - conflictVers.add(conflictVer); - } - else if (conflictVers != null) - conflictVers.add(null); - - if (ttl >= 0) { - if (ttls == null) { - ttls = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - ttls.add(CU.TTL_NOT_CHANGED); - } - } - - if (ttls != null) - ttls.add(ttl); - - if (conflictExpireTime >= 0) { - if (conflictExpireTimes == null) { - conflictExpireTimes = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - } - - if (conflictExpireTimes != null) - conflictExpireTimes.add(conflictExpireTime); - } - - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL. - * @param expireTime Expire time. - */ - @Override public void addNearWriteValue(KeyCacheObject key, - @Nullable CacheObject val, - EntryProcessor entryProcessor, - long ttl, - long expireTime) { - if (nearKeys == null) { - nearKeys = new ArrayList<>(); - - if (forceTransformBackups) { - nearEntryProcessors = new ArrayList<>(); - nearEntryProcessorsBytes = new ArrayList<>(); - } - else - nearVals = new ArrayList<>(); - } - - nearKeys.add(key); - - if (forceTransformBackups) { - assert entryProcessor != null; - - nearEntryProcessors.add(entryProcessor); - } - else - nearVals.add(val); - - if (ttl >= 0) { - if (nearTtls == null) { - nearTtls = new GridLongList(nearKeys.size()); - - for (int i = 0; i < nearKeys.size() - 1; i++) - nearTtls.add(CU.TTL_NOT_CHANGED); - } - } - - if (nearTtls != null) - nearTtls.add(ttl); - - if (expireTime >= 0) { - if (nearExpireTimes == null) { - nearExpireTimes = new GridLongList(nearKeys.size()); - - for (int i = 0; i < nearKeys.size() - 1; i++) - nearExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - } - - if (nearExpireTimes != null) - nearExpireTimes.add(expireTime); - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID. - */ - @Override public UUID nodeId() { - return nodeId; - } - - /** - * @return Subject ID. - */ - @Override public UUID subjectId() { - return subjId; - } - - /** - * @return Task name. - */ - @Override public int taskNameHash() { - return taskNameHash; - } - - /** - * @return Keys size. - */ - @Override public int size() { - return keys.size(); - } - - /** - * @return Keys size. - */ - @Override public int nearSize() { - return nearKeys != null ? nearKeys.size() : 0; - } - - /** - * @return Version assigned on primary node. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * @return Write version. - */ - @Override public GridCacheVersion writeVersion() { - return writeVer; - } - - /** - * @return Cache write synchronization mode. - */ - @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** - * @return Topology version. - */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** - * @return Keys. - */ - @Override public Collection keys() { - return keys; - } - - /** - * @param idx Key index. - * @return Key. - */ - @Override public KeyCacheObject key(int idx) { - return keys.get(idx); - } - - /** - * @param idx Partition index. - * @return Partition id. - */ - @Override public int partitionId(int idx) { - return partIds.get(idx); - } - - /** - * @param updCntr Update counter. - * @return Update counter. - */ - @Override public Long updateCounter(int updCntr) { - if (updateCntrs != null && updCntr < updateCntrs.size()) - return updateCntrs.get(updCntr); - - return null; - } - - /** - * @param idx Near key index. - * @return Key. - */ - @Override public KeyCacheObject nearKey(int idx) { - return nearKeys.get(idx); - } - - /** - * @return Keep binary flag. - */ - @Override public boolean keepBinary() { - return keepBinary; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject value(int idx) { - if (vals != null) - return vals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject previousValue(int idx) { - if (prevVals != null) - return prevVals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject localPreviousValue(int idx) { - assert locPrevVals != null; - - return locPrevVals.get(idx); - } - - /** - * @param idx Key index. - * @return Entry processor. - */ - @Override @Nullable public EntryProcessor entryProcessor(int idx) { - return entryProcessors == null ? null : entryProcessors.get(idx); - } - - /** - * @param idx Near key index. - * @return Value. - */ - @Override @Nullable public CacheObject nearValue(int idx) { - if (nearVals != null) - return nearVals.get(idx); - - return null; - } - - /** - * @param idx Key index. - * @return Transform closure. - */ - @Override @Nullable public EntryProcessor nearEntryProcessor(int idx) { - return nearEntryProcessors == null ? null : nearEntryProcessors.get(idx); - } - - /** - * @param idx Index. - * @return Conflict version. - */ - @Override @Nullable public GridCacheVersion conflictVersion(int idx) { - if (conflictVers != null) { - assert idx >= 0 && idx < conflictVers.size(); - - return conflictVers.get(idx); - } - - return null; - } - - /** - * @param idx Index. - * @return TTL. - */ - @Override public long ttl(int idx) { - if (ttls != null) { - assert idx >= 0 && idx < ttls.size(); - - return ttls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - @Override public long nearTtl(int idx) { - if (nearTtls != null) { - assert idx >= 0 && idx < nearTtls.size(); - - return nearTtls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** - * @param idx Index. - * @return Conflict expire time. - */ - @Override public long conflictExpireTime(int idx) { - if (conflictExpireTimes != null) { - assert idx >= 0 && idx < conflictExpireTimes.size(); - - return conflictExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - @Override public long nearExpireTime(int idx) { - if (nearExpireTimes != null) { - assert idx >= 0 && idx < nearExpireTimes.size(); - - return nearExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** - * @return {@code True} if on response flag changed. - */ - @Override public boolean onResponse() { - return !onRes && (onRes = true); - } - - /** - * @return Optional arguments for entry processor. - */ - @Override @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - prepareMarshalCacheObjects(vals, cctx); - - prepareMarshalCacheObjects(nearKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); - - prepareMarshalCacheObjects(prevVals, cctx); - - if (forceTransformBackups) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); - - if (nearEntryProcessorsBytes == null) - nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - finishUnmarshalCacheObjects(vals, cctx, ldr); - - finishUnmarshalCacheObjects(nearKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearVals, cctx, ldr); - - finishUnmarshalCacheObjects(prevVals, cctx, ldr); - - if (forceTransformBackups) { - if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - - if (nearEntryProcessors == null) - nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); - } - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeMessage("conflictExpireTimes", conflictExpireTimes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeCollection("nearEntryProcessorsBytes", nearEntryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeCollection("nearKeys", nearKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeMessage("nearTtls", nearTtls)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeCollection("prevVals", prevVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 17: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeMessage("ttls", ttls)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeMessage("updateCntrs", updateCntrs)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("writeVer", writeVer)) - 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: - conflictExpireTimes = reader.readMessage("conflictExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - forceTransformBackups = reader.readBoolean("forceTransformBackups"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - keys = reader.readCollection("keys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - nearEntryProcessorsBytes = reader.readCollection("nearEntryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - nearExpireTimes = reader.readMessage("nearExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - nearKeys = reader.readCollection("nearKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - nearTtls = reader.readMessage("nearTtls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 16: - prevVals = reader.readCollection("prevVals", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 17: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 18: - byte syncModeOrd; - - syncModeOrd = reader.readByte("syncMode"); - - if (!reader.isLastRead()) - return false; - - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); - - reader.incrementState(); - - case 19: - taskNameHash = reader.readInt("taskNameHash"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 20: - topVer = reader.readMessage("topVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 21: - ttls = reader.readMessage("ttls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - updateCntrs = reader.readMessage("updateCntrs"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - vals = reader.readCollection("vals", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - writeVer = reader.readMessage("writeVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridDhtAtomicMultipleUpdateRequest.class); - } - - /** {@inheritDoc} */ - @Override public void onAckReceived() { - cleanup(); - } - - /** - * Cleanup values not needed after message was sent. - */ - private void cleanup() { - nearVals = null; - prevVals = null; - - // Do not keep values if they are not needed for continuous query notification. - if (locPrevVals == null) { - keys = null; - vals = null; - locPrevVals = null; - } - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return 38; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 25; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicMultipleUpdateRequest.class, this, "super", super.toString()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java deleted file mode 100644 index cd0b9a6df92cf..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicMultipleUpdateResponse.java +++ /dev/null @@ -1,297 +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.atomic; - -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -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.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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; -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; - -/** - * DHT atomic cache backup update response. - */ -public class GridDhtAtomicMultipleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateResponse { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Future version. */ - private GridCacheVersion futVer; - - /** Failed keys. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List failedKeys; - - /** Update error. */ - @GridDirectTransient - private IgniteCheckedException err; - - /** Serialized update error. */ - private byte[] errBytes; - - /** Evicted readers. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List nearEvicted; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicMultipleUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param futVer Future version. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicMultipleUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { - this.cacheId = cacheId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Future version. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - @Override public void onError(IgniteCheckedException err) { - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Failed keys. - */ - @Override public Collection failedKeys() { - return failedKeys; - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - @Override public void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ArrayList<>(); - - failedKeys.add(key); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * @return Evicted readers. - */ - @Override public Collection nearEvicted() { - return nearEvicted; - } - - /** - * Adds near evicted key.. - * - * @param key Evicted key. - */ - @Override public void addNearEvicted(KeyCacheObject key) { - if (nearEvicted == null) - nearEvicted = new ArrayList<>(); - - nearEvicted.add(key); - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(failedKeys, cctx); - - prepareMarshalCacheObjects(nearEvicted, cctx); - - if (errBytes == null) - errBytes = ctx.marshaller().marshal(err); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridDhtAtomicMultipleUpdateResponse.class); - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return 39; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 7; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicMultipleUpdateResponse.class, this); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java deleted file mode 100644 index b78cc4a8fcf07..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java +++ /dev/null @@ -1,977 +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.atomic; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; -import org.apache.ignite.internal.GridDirectTransient; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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; -import org.apache.ignite.internal.util.GridLongList; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import javax.cache.processor.EntryProcessor; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public class GridDhtAtomicSingleUpdateRequest extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateRequest { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID. */ - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Write version. */ - private GridCacheVersion writeVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - @GridToStringInclude - private KeyCacheObject key; - - @GridToStringInclude - private CacheObject val; - - @GridToStringInclude - private CacheObject prevVal; - - @GridToStringInclude - private GridCacheVersion conflictVer; - - private long ttl = CU.TTL_NOT_CHANGED; - - private long conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - - private long nearTtl = CU.TTL_NOT_CHANGED; - - private long nearExpireTime = CU.EXPIRE_TIME_CALCULATE; - - @GridToStringInclude - private KeyCacheObject nearKey; - - @GridToStringInclude - private CacheObject nearVal; - - @GridDirectTransient - private EntryProcessor entryProcessor; - - private byte[] entryProcessorBytes; - - @GridDirectTransient - private EntryProcessor nearEntryProcessor; - - private byte[] nearEntryProcessorBytes; - - private long updateCntr = -1; - - @GridDirectTransient - private int partId; - - @GridDirectTransient - private CacheObject locPrevVal; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Force transform backups flag. */ - private boolean forceTransformBackups; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** On response flag. Access should be synced on future. */ - @GridDirectTransient - private boolean onRes; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicSingleUpdateRequest() { - // No-op. - } - - /** - * Constructor. - * - * @param cacheId Cache ID. - * @param nodeId Node ID. - * @param futVer Future version. - * @param writeVer Write version for cache values. - * @param invokeArgs Optional arguments for entry processor. - * @param syncMode Cache write synchronization mode. - * @param topVer Topology version. - * @param forceTransformBackups Force transform backups flag. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicSingleUpdateRequest( - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - GridCacheVersion writeVer, - CacheWriteSynchronizationMode syncMode, - @NotNull AffinityTopologyVersion topVer, - boolean forceTransformBackups, - UUID subjId, - int taskNameHash, - Object[] invokeArgs, - boolean addDepInfo, - boolean keepBinary - ) { - assert invokeArgs == null || forceTransformBackups; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.writeVer = writeVer; - this.syncMode = syncMode; - this.topVer = topVer; - this.forceTransformBackups = forceTransformBackups; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.invokeArgs = invokeArgs; - this.addDepInfo = addDepInfo; - this.keepBinary = keepBinary; - } - - /** - * @return Force transform backups flag. - */ - @Override public boolean forceTransformBackups() { - return forceTransformBackups; - } - - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param addPrevVal If {@code true} adds previous value. - * @param prevVal Previous value. - */ - @Override public void addWriteValue(KeyCacheObject key, - @Nullable CacheObject val, - EntryProcessor entryProcessor, - long ttl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - boolean addPrevVal, - int partId, - @Nullable CacheObject prevVal, - @Nullable Long updateIdx, - boolean storeLocPrevVal) { - this.key = key; - - this.partId = partId; - - this.locPrevVal = storeLocPrevVal ? prevVal : null; - - if (forceTransformBackups) { - assert entryProcessor != null; - - this.entryProcessor = entryProcessor; - } - else - this.val = val; - - if (addPrevVal) - this.prevVal = prevVal; - - if (updateIdx != null) - updateCntr = updateIdx; - - this.conflictVer = conflictVer; - - if (ttl >= 0) - this.ttl = ttl; - - if (conflictExpireTime >= 0) - this.conflictExpireTime = conflictExpireTime; - } - - /** - * @param key Key to add. - * @param val Value, {@code null} if should be removed. - * @param entryProcessor Entry processor. - * @param ttl TTL. - * @param expireTime Expire time. - */ - @Override public void addNearWriteValue(KeyCacheObject key, - @Nullable CacheObject val, - EntryProcessor entryProcessor, - long ttl, - long expireTime) { - - nearKey = key; - - if (forceTransformBackups) { - assert entryProcessor != null; - - nearEntryProcessor = entryProcessor; - } - else - nearVal = val; - - if (ttl >= 0) - nearTtl = ttl; - - if (expireTime >= 0) - nearExpireTime = expireTime; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID. - */ - @Override public UUID nodeId() { - return nodeId; - } - - /** - * @return Subject ID. - */ - @Override public UUID subjectId() { - return subjId; - } - - /** - * @return Task name. - */ - @Override public int taskNameHash() { - return taskNameHash; - } - - /** - * @return Keys size. - */ - @Override public int size() { - return key != null ? 1 : 0; - } - - /** - * @return Keys size. - */ - @Override public int nearSize() { - return nearKey != null ? 1 : 0; - } - - /** - * @return Version assigned on primary node. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * @return Write version. - */ - @Override public GridCacheVersion writeVersion() { - return writeVer; - } - - /** - * @return Cache write synchronization mode. - */ - @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** - * @return Topology version. - */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** - * @return Keys. - */ - @Override public Collection keys() { - return Collections.singletonList(key); - } - - /** - * @param idx Key index. - * @return Key. - */ - @Override public KeyCacheObject key(int idx) { - assert idx == 0; - - return key; - } - - /** - * @param idx Partition index. - * @return Partition id. - */ - @Override public int partitionId(int idx) { - assert idx == 0; - - return partId; - } - - /** - * @param updCntr Update counter. - * @return Update counter. - */ - @Override public Long updateCounter(int updCntr) { - if (updCntr != 0) - return null; - - if (updateCntr == -1) - return null; - - return updateCntr; - } - - /** - * @param idx Near key index. - * @return Key. - */ - @Override public KeyCacheObject nearKey(int idx) { - assert idx == 0; - - return nearKey; - } - - /** - * @return Keep binary flag. - */ - @Override public boolean keepBinary() { - return keepBinary; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject value(int idx) { - assert idx == 0; - - return val; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject previousValue(int idx) { - assert idx == 0; - - return prevVal; - } - - /** - * @param idx Key index. - * @return Value. - */ - @Override @Nullable public CacheObject localPreviousValue(int idx) { - assert idx == 0; - - return locPrevVal; - } - - /** - * @param idx Key index. - * @return Entry processor. - */ - @Override @Nullable public EntryProcessor entryProcessor(int idx) { - assert idx == 0; - - return entryProcessor; - } - - /** - * @param idx Near key index. - * @return Value. - */ - @Override @Nullable public CacheObject nearValue(int idx) { - assert idx == 0; - - return nearVal; - } - - /** - * @param idx Key index. - * @return Transform closure. - */ - @Override @Nullable public EntryProcessor nearEntryProcessor(int idx) { - assert idx == 0; - - return nearEntryProcessor; - } - - /** - * @param idx Index. - * @return Conflict version. - */ - @Override @Nullable public GridCacheVersion conflictVersion(int idx) { - assert idx == 0; - - return conflictVer; - } - - /** - * @param idx Index. - * @return TTL. - */ - @Override public long ttl(int idx) { - assert idx == 0; - - return ttl; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - @Override public long nearTtl(int idx) { - assert idx == 0; - - return nearTtl; - } - - /** - * @param idx Index. - * @return Conflict expire time. - */ - @Override public long conflictExpireTime(int idx) { - assert idx == 0; - - return conflictExpireTime; - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - @Override public long nearExpireTime(int idx) { - assert idx == 0; - - return nearExpireTime; - } - - /** - * @return {@code True} if on response flag changed. - */ - @Override public boolean onResponse() { - return !onRes && (onRes = true); - } - - /** - * @return Optional arguments for entry processor. - */ - @Override @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(key, cctx); - - prepareMarshalCacheObject(val, cctx); - - prepareMarshalCacheObject(nearKey, cctx); - - prepareMarshalCacheObject(nearVal, cctx); - - prepareMarshalCacheObject(prevVal, cctx); - - if (forceTransformBackups) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - - if (entryProcessorBytes == null) - entryProcessorBytes = marshal(entryProcessor, cctx); - - if (nearEntryProcessorBytes == null) - nearEntryProcessorBytes = marshal(nearEntryProcessor, cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObject(key, cctx, ldr); - - finishUnmarshalCacheObject(val, cctx, ldr); - - finishUnmarshalCacheObject(nearKey, cctx, ldr); - - finishUnmarshalCacheObject(nearVal, cctx, ldr); - - finishUnmarshalCacheObject(prevVal, cctx, ldr); - - if (forceTransformBackups) { - if (entryProcessor == null) - entryProcessor = unmarshal(entryProcessorBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - - if (nearEntryProcessor == null) - nearEntryProcessor = unmarshal(nearEntryProcessorBytes, ctx, ldr); - } - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeLong("conflictExpireTime", conflictExpireTime)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeMessage("conflictVer", conflictVer)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeByteArray("entryProcessorBytes", entryProcessorBytes)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeMessage("key", key)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeByteArray("nearEntryProcessorBytes", nearEntryProcessorBytes)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeLong("nearExpireTime", nearExpireTime)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeMessage("nearKey", nearKey)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeLong("nearTtl", nearTtl)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeMessage("nearVal", nearVal)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeMessage("prevVal", prevVal)) - return false; - - writer.incrementState(); - - case 17: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeLong("ttl", ttl)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeLong("updateCntr", updateCntr)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeMessage("val", val)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("writeVer", writeVer)) - 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: - conflictExpireTime = reader.readLong("conflictExpireTime"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictVer = reader.readMessage("conflictVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - entryProcessorBytes = reader.readByteArray("entryProcessorBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - forceTransformBackups = reader.readBoolean("forceTransformBackups"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - key = reader.readMessage("key"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - nearEntryProcessorBytes = reader.readByteArray("nearEntryProcessorBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - nearExpireTime = reader.readLong("nearExpireTime"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - nearKey = reader.readMessage("nearKey"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - nearTtl = reader.readLong("nearTtl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - nearVal = reader.readMessage("nearVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 16: - prevVal = reader.readMessage("prevVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 17: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 18: - byte syncModeOrd; - - syncModeOrd = reader.readByte("syncMode"); - - if (!reader.isLastRead()) - return false; - - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); - - reader.incrementState(); - - case 19: - taskNameHash = reader.readInt("taskNameHash"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 20: - topVer = reader.readMessage("topVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 21: - ttl = reader.readLong("ttl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - updateCntr = reader.readLong("updateCntr"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - val = reader.readMessage("val"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - writeVer = reader.readMessage("writeVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridDhtAtomicSingleUpdateRequest.class); - } - - /** {@inheritDoc} */ - @Override public void onAckReceived() { - cleanup(); - } - - /** - * Cleanup values not needed after message was sent. - */ - private void cleanup() { - nearVal = null; - prevVal = null; - - // Do not keep values if they are not needed for continuous query notification. - if (locPrevVal == null) { - key = null; - val = null; - locPrevVal = null; - } - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return -25; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 25; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicSingleUpdateRequest.class, this, "super", super.toString()); - } -} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java deleted file mode 100644 index 044efa9c53929..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateResponse.java +++ /dev/null @@ -1,287 +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.atomic; - -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.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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; -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; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class GridDhtAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridDhtAtomicUpdateResponse { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Future version. */ - private GridCacheVersion futVer; - - @GridToStringInclude - private KeyCacheObject failedKey; - - @GridToStringInclude - private KeyCacheObject nearEvicted; - - /** Update error. */ - @GridDirectTransient - private IgniteCheckedException err; - - /** Serialized update error. */ - private byte[] errBytes; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridDhtAtomicSingleUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param futVer Future version. - * @param addDepInfo Deployment info. - */ - public GridDhtAtomicSingleUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { - this.cacheId = cacheId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Future version. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - @Override public void onError(IgniteCheckedException err) { - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Failed keys. - */ - @Override public Collection failedKeys() { - return failedKey != null ? Collections.singletonList(failedKey) : null; - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - @Override public void addFailedKey(KeyCacheObject key, Throwable e) { - failedKey = key; - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * @return Evicted readers. - */ - @Override public Collection nearEvicted() { - return nearEvicted != null ? Collections.singletonList(nearEvicted) : null; - } - - /** - * Adds near evicted key.. - * - * @param key Evicted key. - */ - @Override public void addNearEvicted(KeyCacheObject key) { - nearEvicted = key; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(failedKey, cctx); - - prepareMarshalCacheObject(nearEvicted, cctx); - - if (errBytes == null) - errBytes = ctx.marshaller().marshal(err); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObject(failedKey, cctx, ldr); - - finishUnmarshalCacheObject(nearEvicted, cctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeMessage("failedKey", failedKey)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeMessage("nearEvicted", nearEvicted)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - failedKey = reader.readMessage("failedKey"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - nearEvicted = reader.readMessage("nearEvicted"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridDhtAtomicSingleUpdateResponse.class); - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return -26; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 7; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridDhtAtomicSingleUpdateResponse.class, this); - } -} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 6823d77d429d1..58d704de63135 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -35,7 +35,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry; import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryListener; @@ -55,7 +54,8 @@ /** * DHT atomic cache backup update future. */ -public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture { +public class GridDhtAtomicUpdateFuture extends GridFutureAdapter + implements GridCacheAtomicFuture { /** */ private static final long serialVersionUID = 0L; @@ -115,7 +115,8 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter implement */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, - CI2 completionCb, + CI2 completionCb, GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, GridNearAtomicUpdateResponse updateRes @@ -213,6 +214,11 @@ private boolean registerResponse(UUID nodeId) { return null; } + /** {@inheritDoc} */ + @Override public Collection keys() { + return keys; + } + /** * @param entry Entry to map. * @param val Value to write. @@ -251,34 +257,19 @@ public void addWriteEntry(GridDhtCacheEntry entry, GridDhtAtomicUpdateRequest updateReq = mappings.get(nodeId); if (updateReq == null) { - if (this.updateReq instanceof GridNearAtomicSingleUpdateRequest) - updateReq = new GridDhtAtomicSingleUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); - else - updateReq = new GridDhtAtomicMultipleUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); + updateReq = new GridDhtAtomicUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); mappings.put(nodeId, updateReq); } @@ -347,34 +338,19 @@ public void addNearWriteEntries(Iterable readers, if (node == null) continue; - if (this.updateReq instanceof GridNearAtomicSingleUpdateRequest) - updateReq = new GridDhtAtomicSingleUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); - else - updateReq = new GridDhtAtomicMultipleUpdateRequest( - cctx.cacheId(), - nodeId, - futVer, - writeVer, - syncMode, - topVer, - forceTransformBackups, - this.updateReq.subjectId(), - this.updateReq.taskNameHash(), - forceTransformBackups ? this.updateReq.invokeArguments() : null, - cctx.deploymentEnabled(), - this.updateReq.keepBinary()); + updateReq = new GridDhtAtomicUpdateRequest( + cctx.cacheId(), + nodeId, + futVer, + writeVer, + syncMode, + topVer, + forceTransformBackups, + this.updateReq.subjectId(), + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null, + cctx.deploymentEnabled(), + this.updateReq.keepBinary()); mappings.put(nodeId, updateReq); } @@ -401,8 +377,7 @@ public void addNearWriteEntries(Iterable readers, if (!mappings.isEmpty() && lsnrs != null) { Collection hndKeys = new ArrayList<>(keys.size()); - exit: - for (GridDhtAtomicUpdateRequest req : mappings.values()) { + exit: for (GridDhtAtomicUpdateRequest req : mappings.values()) { for (int i = 0; i < req.size(); i++) { KeyCacheObject key = req.key(i); @@ -485,7 +460,7 @@ public void map() { if (log.isDebugEnabled()) log.debug("Sending DHT atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - cctx.io().send(req.nodeId(), (GridCacheMessage)req, cctx.ioPolicy()); + cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ignored) { U.warn(log, "Failed to send update request to backup node because it left grid: " + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java index 280b98e144955..c8e33c2e6a917 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java @@ -1,44 +1,250 @@ /* + * 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 * - * * 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. + * 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.atomic; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import javax.cache.processor.EntryProcessor; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.cache.processor.EntryProcessor; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.UUID; -public interface GridDhtAtomicUpdateRequest { +/** + * Lite dht cache backup update request. + */ +public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID. */ + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Write version. */ + private GridCacheVersion writeVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Previous values. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List prevVals; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** TTLs. */ + private GridLongList ttls; + + /** Conflict expire time. */ + private GridLongList conflictExpireTimes; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Near cache keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearKeys; + + /** Values to update. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Force transform backups flag. */ + private boolean forceTransformBackups; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Near entry processors. */ + @GridDirectTransient + private List> nearEntryProcessors; - boolean forceTransformBackups(); + /** Near entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List nearEntryProcessorsBytes; - void addWriteValue(KeyCacheObject key, + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Partition. */ + private GridLongList updateCntrs; + + /** On response flag. Access should be synced on future. */ + @GridDirectTransient + private boolean onRes; + + /** */ + @GridDirectTransient + private List partIds; + + /** */ + @GridDirectTransient + private List locPrevVals; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param writeVer Write version for cache values. + * @param invokeArgs Optional arguments for entry processor. + * @param syncMode Cache write synchronization mode. + * @param topVer Topology version. + * @param forceTransformBackups Force transform backups flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + GridCacheVersion writeVer, + CacheWriteSynchronizationMode syncMode, + @NotNull AffinityTopologyVersion topVer, + boolean forceTransformBackups, + UUID subjId, + int taskNameHash, + Object[] invokeArgs, + boolean addDepInfo, + boolean keepBinary + ) { + assert invokeArgs == null || forceTransformBackups; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.writeVer = writeVer; + this.syncMode = syncMode; + this.topVer = topVer; + this.forceTransformBackups = forceTransformBackups; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.invokeArgs = invokeArgs; + this.addDepInfo = addDepInfo; + this.keepBinary = keepBinary; + + keys = new ArrayList<>(); + partIds = new ArrayList<>(); + + if (forceTransformBackups) { + entryProcessors = new ArrayList<>(); + entryProcessorsBytes = new ArrayList<>(); + } + else + vals = new ArrayList<>(); + } + + /** + * @return Force transform backups flag. + */ + public boolean forceTransformBackups() { + return forceTransformBackups; + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param addPrevVal If {@code true} adds previous value. + * @param partId Partition. + * @param prevVal Previous value. + * @param updateCntr Update counter. + * @param storeLocPrevVal If {@code true} stores previous value. + */ + public void addWriteValue(KeyCacheObject key, @Nullable CacheObject val, EntryProcessor entryProcessor, long ttl, @@ -47,86 +253,843 @@ void addWriteValue(KeyCacheObject key, boolean addPrevVal, int partId, @Nullable CacheObject prevVal, - @Nullable Long updateIdx, - boolean storeLocPrevVal); + @Nullable Long updateCntr, + boolean storeLocPrevVal) { + keys.add(key); + + partIds.add(partId); + + if (storeLocPrevVal) { + if (locPrevVals == null) + locPrevVals = new ArrayList<>(); + + locPrevVals.add(prevVal); + } + + if (forceTransformBackups) { + assert entryProcessor != null; + + entryProcessors.add(entryProcessor); + } + else + vals.add(val); + + if (addPrevVal) { + if (prevVals == null) + prevVals = new ArrayList<>(); + + prevVals.add(prevVal); + } + + if (updateCntr != null) { + if (updateCntrs == null) + updateCntrs = new GridLongList(); + + updateCntrs.add(updateCntr); + } + + // In case there is no conflict, do not create the list. + if (conflictVer != null) { + if (conflictVers == null) { + conflictVers = new ArrayList<>(); + + for (int i = 0; i < keys.size() - 1; i++) + conflictVers.add(null); + } + + conflictVers.add(conflictVer); + } + else if (conflictVers != null) + conflictVers.add(null); + + if (ttl >= 0) { + if (ttls == null) { + ttls = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + ttls.add(CU.TTL_NOT_CHANGED); + } + } - void addNearWriteValue(KeyCacheObject key, + if (ttls != null) + ttls.add(ttl); + + if (conflictExpireTime >= 0) { + if (conflictExpireTimes == null) { + conflictExpireTimes = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + } + + if (conflictExpireTimes != null) + conflictExpireTimes.add(conflictExpireTime); + } + + /** + * @param key Key to add. + * @param val Value, {@code null} if should be removed. + * @param entryProcessor Entry processor. + * @param ttl TTL. + * @param expireTime Expire time. + */ + public void addNearWriteValue(KeyCacheObject key, @Nullable CacheObject val, EntryProcessor entryProcessor, long ttl, - long expireTime); + long expireTime) { + if (nearKeys == null) { + nearKeys = new ArrayList<>(); + + if (forceTransformBackups) { + nearEntryProcessors = new ArrayList<>(); + nearEntryProcessorsBytes = new ArrayList<>(); + } + else + nearVals = new ArrayList<>(); + } + + nearKeys.add(key); + + if (forceTransformBackups) { + assert entryProcessor != null; + + nearEntryProcessors.add(entryProcessor); + } + else + nearVals.add(val); + + if (ttl >= 0) { + if (nearTtls == null) { + nearTtls = new GridLongList(nearKeys.size()); + + for (int i = 0; i < nearKeys.size() - 1; i++) + nearTtls.add(CU.TTL_NOT_CHANGED); + } + } + + if (nearTtls != null) + nearTtls.add(ttl); + + if (expireTime >= 0) { + if (nearExpireTimes == null) { + nearExpireTimes = new GridLongList(nearKeys.size()); + + for (int i = 0; i < nearKeys.size() - 1; i++) + nearExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + } + + if (nearExpireTimes != null) + nearExpireTimes.add(expireTime); + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID. + */ + public UUID nodeId() { + return nodeId; + } + + /** + * @return Subject ID. + */ + public UUID subjectId() { + return subjId; + } + + /** + * @return Task name. + */ + public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Keys size. + */ + public int size() { + return keys.size(); + } + + /** + * @return Keys size. + */ + public int nearSize() { + return nearKeys != null ? nearKeys.size() : 0; + } + + /** + * @return Version assigned on primary node. + */ + public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * @return Write version. + */ + public GridCacheVersion writeVersion() { + return writeVer; + } + + /** + * @return Cache write synchronization mode. + */ + public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Keys. + */ + public Collection keys() { + return keys; + } + + /** + * @param idx Key index. + * @return Key. + */ + public KeyCacheObject key(int idx) { + return keys.get(idx); + } + + /** + * @param idx Partition index. + * @return Partition id. + */ + public int partitionId(int idx) { + return partIds.get(idx); + } + + /** + * @param updCntr Update counter. + * @return Update counter. + */ + public Long updateCounter(int updCntr) { + if (updateCntrs != null && updCntr < updateCntrs.size()) + return updateCntrs.get(updCntr); + + return null; + } + + /** + * @param idx Near key index. + * @return Key. + */ + public KeyCacheObject nearKey(int idx) { + return nearKeys.get(idx); + } + + /** + * @return Keep binary flag. + */ + public boolean keepBinary() { + return keepBinary; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Nullable public CacheObject value(int idx) { + if (vals != null) + return vals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Nullable public CacheObject previousValue(int idx) { + if (prevVals != null) + return prevVals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Value. + */ + @Nullable public CacheObject localPreviousValue(int idx) { + assert locPrevVals != null; + + return locPrevVals.get(idx); + } + + /** + * @param idx Key index. + * @return Entry processor. + */ + @Nullable public EntryProcessor entryProcessor(int idx) { + return entryProcessors == null ? null : entryProcessors.get(idx); + } + + /** + * @param idx Near key index. + * @return Value. + */ + @Nullable public CacheObject nearValue(int idx) { + if (nearVals != null) + return nearVals.get(idx); + + return null; + } + + /** + * @param idx Key index. + * @return Transform closure. + */ + @Nullable public EntryProcessor nearEntryProcessor(int idx) { + return nearEntryProcessors == null ? null : nearEntryProcessors.get(idx); + } + + /** + * @param idx Index. + * @return Conflict version. + */ + @Nullable public GridCacheVersion conflictVersion(int idx) { + if (conflictVers != null) { + assert idx >= 0 && idx < conflictVers.size(); + + return conflictVers.get(idx); + } + + return null; + } + + /** + * @param idx Index. + * @return TTL. + */ + public long ttl(int idx) { + if (ttls != null) { + assert idx >= 0 && idx < ttls.size(); + + return ttls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + public long nearTtl(int idx) { + if (nearTtls != null) { + assert idx >= 0 && idx < nearTtls.size(); + + return nearTtls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } + + /** + * @param idx Index. + * @return Conflict expire time. + */ + public long conflictExpireTime(int idx) { + if (conflictExpireTimes != null) { + assert idx >= 0 && idx < conflictExpireTimes.size(); + + return conflictExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + public long nearExpireTime(int idx) { + if (nearExpireTimes != null) { + assert idx >= 0 && idx < nearExpireTimes.size(); + + return nearExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } + + /** + * @return {@code True} if on response flag changed. + */ + public boolean onResponse() { + return !onRes && (onRes = true); + } + + /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(keys, cctx); + + prepareMarshalCacheObjects(vals, cctx); + + prepareMarshalCacheObjects(nearKeys, cctx); + + prepareMarshalCacheObjects(nearVals, cctx); + + prepareMarshalCacheObjects(prevVals, cctx); + + if (forceTransformBackups) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + + if (entryProcessorsBytes == null) + entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + + if (nearEntryProcessorsBytes == null) + nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx); + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(keys, cctx, ldr); + + finishUnmarshalCacheObjects(vals, cctx, ldr); + + finishUnmarshalCacheObjects(nearKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearVals, cctx, ldr); + + finishUnmarshalCacheObjects(prevVals, cctx, ldr); + + if (forceTransformBackups) { + if (entryProcessors == null) + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + + if (nearEntryProcessors == null) + nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); + } + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeMessage("conflictExpireTimes", conflictExpireTimes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeBoolean("forceTransformBackups", forceTransformBackups)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeCollection("nearEntryProcessorsBytes", nearEntryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeCollection("nearKeys", nearKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeMessage("nearTtls", nearTtls)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeCollection("prevVals", prevVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeMessage("ttls", ttls)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeMessage("updateCntrs", updateCntrs)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("writeVer", writeVer)) + 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: + conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + forceTransformBackups = reader.readBoolean("forceTransformBackups"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + keys = reader.readCollection("keys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + nearEntryProcessorsBytes = reader.readCollection("nearEntryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + nearExpireTimes = reader.readMessage("nearExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + nearKeys = reader.readCollection("nearKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + nearTtls = reader.readMessage("nearTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); - int lookupIndex(); + case 16: + prevVals = reader.readCollection("prevVals", MessageCollectionItemType.MSG); - UUID nodeId(); + if (!reader.isLastRead()) + return false; - UUID subjectId(); + reader.incrementState(); - int taskNameHash(); + case 17: + subjId = reader.readUuid("subjId"); - int size(); + if (!reader.isLastRead()) + return false; - int nearSize(); + reader.incrementState(); - GridCacheVersion futureVersion(); + case 18: + byte syncModeOrd; - GridCacheVersion writeVersion(); + syncModeOrd = reader.readByte("syncMode"); - CacheWriteSynchronizationMode writeSynchronizationMode(); + if (!reader.isLastRead()) + return false; - AffinityTopologyVersion topologyVersion(); + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); - Collection keys(); + reader.incrementState(); - KeyCacheObject key(int idx); + case 19: + taskNameHash = reader.readInt("taskNameHash"); - int partitionId(int idx); + if (!reader.isLastRead()) + return false; - Long updateCounter(int updCntr); + reader.incrementState(); - KeyCacheObject nearKey(int idx); + case 20: + topVer = reader.readMessage("topVer"); - boolean keepBinary(); + if (!reader.isLastRead()) + return false; - @Nullable CacheObject value(int idx); + reader.incrementState(); - @Nullable CacheObject previousValue(int idx); + case 21: + ttls = reader.readMessage("ttls"); - @Nullable CacheObject localPreviousValue(int idx); + if (!reader.isLastRead()) + return false; - @Nullable EntryProcessor entryProcessor(int idx); + reader.incrementState(); - @Nullable CacheObject nearValue(int idx); + case 22: + updateCntrs = reader.readMessage("updateCntrs"); - @Nullable EntryProcessor nearEntryProcessor(int idx); + if (!reader.isLastRead()) + return false; - @Nullable GridCacheVersion conflictVersion(int idx); + reader.incrementState(); - long ttl(int idx); + case 23: + vals = reader.readCollection("vals", MessageCollectionItemType.MSG); - long nearTtl(int idx); + if (!reader.isLastRead()) + return false; - long conflictExpireTime(int idx); + reader.incrementState(); - long nearExpireTime(int idx); + case 24: + writeVer = reader.readMessage("writeVer"); - boolean onResponse(); + if (!reader.isLastRead()) + return false; - @Nullable Object[] invokeArguments(); + reader.incrementState(); - void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; + } - void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; + return reader.afterMessageRead(GridDhtAtomicUpdateRequest.class); + } - boolean addDeploymentInfo(); + /** {@inheritDoc} */ + @Override public void onAckReceived() { + cleanup(); + } - boolean writeTo(ByteBuffer buf, MessageWriter writer); + /** + * Cleanup values not needed after message was sent. + */ + private void cleanup() { + nearVals = null; + prevVals = null; - boolean readFrom(ByteBuffer buf, MessageReader reader); + // Do not keep values if they are not needed for continuous query notification. + if (locPrevVals == null) { + keys = null; + vals = null; + locPrevVals = null; + } + } - byte directType(); + /** {@inheritDoc} */ + @Override public byte directType() { + return 38; + } - byte fieldsCount(); + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 25; + } - IgniteCheckedException classError(); + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicUpdateRequest.class, this, "super", super.toString()); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java index a74fed60846da..8f1d9a2da9259 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java @@ -1,63 +1,297 @@ /* + * 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 * - * * 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. + * 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.atomic; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; 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.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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; +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; -import java.nio.ByteBuffer; -import java.util.Collection; -public interface GridDhtAtomicUpdateResponse { - int lookupIndex(); +/** + * DHT atomic cache backup update response. + */ +public class GridDhtAtomicUpdateResponse extends GridCacheMessage implements GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Future version. */ + private GridCacheVersion futVer; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List failedKeys; + + /** Update error. */ + @GridDirectTransient + private IgniteCheckedException err; + + /** Serialized update error. */ + private byte[] errBytes; + + /** Evicted readers. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List nearEvicted; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridDhtAtomicUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param futVer Future version. + * @param addDepInfo Deployment info. + */ + public GridDhtAtomicUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) { + this.cacheId = cacheId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Future version. + */ + public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + public void onError(IgniteCheckedException err){ + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Failed keys. + */ + public Collection failedKeys() { + return failedKeys; + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + public void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ArrayList<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * @return Evicted readers. + */ + public Collection nearEvicted() { + return nearEvicted; + } + + /** + * Adds near evicted key.. + * + * @param key Evicted key. + */ + public void addNearEvicted(KeyCacheObject key) { + if (nearEvicted == null) + nearEvicted = new ArrayList<>(); + + nearEvicted.add(key); + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(failedKeys, cctx); + + prepareMarshalCacheObjects(nearEvicted, cctx); + + if (errBytes == null) + errBytes = ctx.marshaller().marshal(err); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("nearEvicted", nearEvicted, MessageCollectionItemType.MSG)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; - GridCacheVersion futureVersion(); + reader.incrementState(); - void onError(IgniteCheckedException err); + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); - IgniteCheckedException error(); + if (!reader.isLastRead()) + return false; - Collection failedKeys(); + reader.incrementState(); - void addFailedKey(KeyCacheObject key, Throwable e); + case 5: + futVer = reader.readMessage("futVer"); - Collection nearEvicted(); + if (!reader.isLastRead()) + return false; - void addNearEvicted(KeyCacheObject key); + reader.incrementState(); - void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; + case 6: + nearEvicted = reader.readCollection("nearEvicted", MessageCollectionItemType.MSG); - void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; + if (!reader.isLastRead()) + return false; - boolean addDeploymentInfo(); + reader.incrementState(); - boolean writeTo(ByteBuffer buf, MessageWriter writer); + } - boolean readFrom(ByteBuffer buf, MessageReader reader); + return reader.afterMessageRead(GridDhtAtomicUpdateResponse.class); + } - byte directType(); + /** {@inheritDoc} */ + @Override public byte directType() { + return 39; + } - byte fieldsCount(); + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 7; + } - long messageId(); + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridDhtAtomicUpdateResponse.class, this); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java deleted file mode 100644 index 86de2e2c63444..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateRequest.java +++ /dev/null @@ -1,988 +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.atomic; - -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.processor.EntryProcessor; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectCollection; -import org.apache.ignite.internal.GridDirectTransient; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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.IgniteExternalizableExpiryPolicy; -import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.GridLongList; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; - -/** - * Lite DHT cache update request sent from near node to primary node. - */ -public class GridNearAtomicMultipleUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequest, GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Target node ID. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Fast map flag. */ - private boolean fastMap; - - /** Update version. Set to non-null if fastMap is {@code true}. */ - private GridCacheVersion updateVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ - private boolean topLocked; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Update operation. */ - private GridCacheOperation op; - - /** Keys to update. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List keys; - - /** Values to update. */ - @GridDirectCollection(CacheObject.class) - private List vals; - - /** Entry processors. */ - @GridDirectTransient - private List> entryProcessors; - - /** Entry processors bytes. */ - @GridDirectCollection(byte[].class) - private List entryProcessorsBytes; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Conflict versions. */ - @GridDirectCollection(GridCacheVersion.class) - private List conflictVers; - - /** Conflict TTLs. */ - private GridLongList conflictTtls; - - /** Conflict expire times. */ - private GridLongList conflictExpireTimes; - - /** Return value flag. */ - private boolean retval; - - /** Expiry policy. */ - @GridDirectTransient - private ExpiryPolicy expiryPlc; - - /** Expiry policy bytes. */ - private byte[] expiryPlcBytes; - - /** Filter. */ - private CacheEntryPredicate[] filter; - - /** Flag indicating whether request contains primary keys. */ - private boolean hasPrimary; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Skip write-through to a persistent storage. */ - private boolean skipStore; - - /** */ - private boolean clientReq; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** */ - @GridDirectTransient - private GridNearAtomicUpdateResponse res; - - /** Maximum possible size of inner collections. */ - @GridDirectTransient - private int initSize; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridNearAtomicMultipleUpdateRequest() { - // No-op. - } - - /** - * Constructor. - * - * @param cacheId Cache ID. - * @param nodeId Node ID. - * @param futVer Future version. - * @param fastMap Fast map scheme flag. - * @param updateVer Update version set if fast map is performed. - * @param topVer Topology version. - * @param topLocked Topology locked flag. - * @param syncMode Synchronization mode. - * @param op Cache update operation. - * @param retval Return value required flag. - * @param expiryPlc Expiry policy. - * @param invokeArgs Optional arguments for entry processor. - * @param filter Optional filter for atomic check. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param skipStore Skip write-through to a persistent storage. - * @param keepBinary Keep binary flag. - * @param clientReq Client node request flag. - * @param addDepInfo Deployment info flag. - * @param maxEntryCnt Maximum entries count. - */ - public GridNearAtomicMultipleUpdateRequest( - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - boolean fastMap, - @Nullable GridCacheVersion updateVer, - @NotNull AffinityTopologyVersion topVer, - boolean topLocked, - CacheWriteSynchronizationMode syncMode, - GridCacheOperation op, - boolean retval, - @Nullable ExpiryPolicy expiryPlc, - @Nullable Object[] invokeArgs, - @Nullable CacheEntryPredicate[] filter, - @Nullable UUID subjId, - int taskNameHash, - boolean skipStore, - boolean keepBinary, - boolean clientReq, - boolean addDepInfo, - int maxEntryCnt - ) { - assert futVer != null; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.fastMap = fastMap; - this.updateVer = updateVer; - - this.topVer = topVer; - this.topLocked = topLocked; - this.syncMode = syncMode; - this.op = op; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.invokeArgs = invokeArgs; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.clientReq = clientReq; - this.addDepInfo = addDepInfo; - - // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries - // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys - // participate in request. As such, we know upper bound of all collections in request. If this bound is lower - // than 10, we use it. - initSize = Math.min(maxEntryCnt, 10); - - keys = new ArrayList<>(initSize); - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** {@inheritDoc} */ - @Override public UUID nodeId() { - return nodeId; - } - - /** {@inheritDoc} */ - @Override public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** {@inheritDoc} */ - @Override public UUID subjectId() { - return subjId; - } - - /** {@inheritDoc} */ - @Override public int taskNameHash() { - return taskNameHash; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** {@inheritDoc} */ - @Override public boolean fastMap() { - return fastMap; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion updateVersion() { - return updateVer; - } - - /** {@inheritDoc} */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** {@inheritDoc} */ - @Override public boolean topologyLocked() { - return topLocked; - } - - /** {@inheritDoc} */ - @Override public boolean clientRequest() { - return clientReq; - } - - /** {@inheritDoc} */ - @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** {@inheritDoc} */ - @Override public ExpiryPolicy expiry() { - return expiryPlc; - } - - /** {@inheritDoc} */ - @Override public boolean returnValue() { - return retval; - } - - /** {@inheritDoc} */ - @Nullable public CacheEntryPredicate[] filter() { - return filter; - } - - /** {@inheritDoc} */ - @Override public boolean skipStore() { - return skipStore; - } - - /** {@inheritDoc} */ - @Override public boolean keepBinary() { - return keepBinary; - } - - /** - * @param key Key to add. - * @param val Optional update value. - * @param conflictTtl Conflict TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param primary If given key is primary on this mapping. - */ - @SuppressWarnings("unchecked") - public void addUpdateEntry(KeyCacheObject key, - @Nullable Object val, - long conflictTtl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - boolean primary) { - EntryProcessor entryProcessor = null; - - if (op == TRANSFORM) { - assert val instanceof EntryProcessor : val; - - entryProcessor = (EntryProcessor)val; - } - - assert val != null || op == DELETE; - - keys.add(key); - - if (entryProcessor != null) { - if (entryProcessors == null) - entryProcessors = new ArrayList<>(initSize); - - entryProcessors.add(entryProcessor); - } - else if (val != null) { - assert val instanceof CacheObject : val; - - if (vals == null) - vals = new ArrayList<>(initSize); - - vals.add((CacheObject)val); - } - - hasPrimary |= primary; - - // In case there is no conflict, do not create the list. - if (conflictVer != null) { - if (conflictVers == null) { - conflictVers = new ArrayList<>(initSize); - - for (int i = 0; i < keys.size() - 1; i++) - conflictVers.add(null); - } - - conflictVers.add(conflictVer); - } - else if (conflictVers != null) - conflictVers.add(null); - - if (conflictTtl >= 0) { - if (conflictTtls == null) { - conflictTtls = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictTtls.add(CU.TTL_NOT_CHANGED); - } - - conflictTtls.add(conflictTtl); - } - - if (conflictExpireTime >= 0) { - if (conflictExpireTimes == null) { - conflictExpireTimes = new GridLongList(keys.size()); - - for (int i = 0; i < keys.size() - 1; i++) - conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); - } - - conflictExpireTimes.add(conflictExpireTime); - } - } - - /** {@inheritDoc} */ - @Override public List keys() { - return keys; - } - - /** {@inheritDoc} */ - @Override public List values() { - return op == TRANSFORM ? entryProcessors : vals; - } - - /** {@inheritDoc} */ - @Override public GridCacheOperation operation() { - return op; - } - - /** {@inheritDoc} */ - @Override @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public CacheObject value(int idx) { - assert op == UPDATE : op; - - return vals.get(idx); - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public EntryProcessor entryProcessor(int idx) { - assert op == TRANSFORM : op; - - return entryProcessors.get(idx); - } - - /** {@inheritDoc} */ - @Override public CacheObject writeValue(int idx) { - if (vals != null) - return vals.get(idx); - - return null; - } - - /** {@inheritDoc} */ - @Override @Nullable public List conflictVersions() { - return conflictVers; - } - - /** {@inheritDoc} */ - @Override @Nullable public GridCacheVersion conflictVersion(int idx) { - if (conflictVers != null) { - assert idx >= 0 && idx < conflictVers.size(); - - return conflictVers.get(idx); - } - - return null; - } - - /** {@inheritDoc} */ - @Override public long conflictTtl(int idx) { - if (conflictTtls != null) { - assert idx >= 0 && idx < conflictTtls.size(); - - return conflictTtls.get(idx); - } - - return CU.TTL_NOT_CHANGED; - } - - /** {@inheritDoc} */ - @Override public long conflictExpireTime(int idx) { - if (conflictExpireTimes != null) { - assert idx >= 0 && idx < conflictExpireTimes.size(); - - return conflictExpireTimes.get(idx); - } - - return CU.EXPIRE_TIME_CALCULATE; - } - - /** {@inheritDoc} */ - @Override public boolean hasPrimary() { - return hasPrimary; - } - - /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { - if (this.res == null) { - this.res = res; - - return true; - } - - return false; - } - - /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicUpdateResponse response() { - return res; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - if (filter != null) { - boolean hasFilter = false; - - for (CacheEntryPredicate p : filter) { - if (p != null) { - hasFilter = true; - - p.prepareMarshal(cctx); - } - } - - if (!hasFilter) - filter = null; - } - - if (expiryPlc != null && expiryPlcBytes == null) - expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); - - if (op == TRANSFORM) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - } - else - prepareMarshalCacheObjects(vals, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - if (op == TRANSFORM) { - if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - } - else - finishUnmarshalCacheObjects(vals, cctx, ldr); - - if (filter != null) { - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - - if (expiryPlcBytes != null && expiryPlc == null) - expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeBoolean("clientReq", clientReq)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("conflictTtls", conflictTtls)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("fastMap", fastMap)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeBoolean("hasPrimary", hasPrimary)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 17: - if (!writer.writeBoolean("retval", retval)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeBoolean("skipStore", skipStore)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeBoolean("topLocked", topLocked)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("updateVer", updateVer)) - return false; - - writer.incrementState(); - - case 25: - if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) - 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: - clientReq = reader.readBoolean("clientReq"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictExpireTimes = reader.readMessage("conflictExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - conflictTtls = reader.readMessage("conflictTtls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - fastMap = reader.readBoolean("fastMap"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - hasPrimary = reader.readBoolean("hasPrimary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - keys = reader.readCollection("keys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 16: - byte opOrd; - - opOrd = reader.readByte("op"); - - if (!reader.isLastRead()) - return false; - - op = GridCacheOperation.fromOrdinal(opOrd); - - reader.incrementState(); - - case 17: - retval = reader.readBoolean("retval"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 18: - skipStore = reader.readBoolean("skipStore"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 19: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 20: - byte syncModeOrd; - - syncModeOrd = reader.readByte("syncMode"); - - if (!reader.isLastRead()) - return false; - - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); - - reader.incrementState(); - - case 21: - taskNameHash = reader.readInt("taskNameHash"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - topLocked = reader.readBoolean("topLocked"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - topVer = reader.readMessage("topVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - updateVer = reader.readMessage("updateVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 25: - vals = reader.readCollection("vals", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridNearAtomicMultipleUpdateRequest.class); - } - - /** {@inheritDoc} */ - @Override public void cleanup(boolean clearKeys) { - vals = null; - entryProcessors = null; - entryProcessorsBytes = null; - invokeArgs = null; - invokeArgsBytes = null; - - if (clearKeys) - keys = null; - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return 40; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 26; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicMultipleUpdateRequest.class, this, "filter", Arrays.toString(filter), - "parent", super.toString()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java deleted file mode 100644 index d22acc4ce7e5f..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicMultipleUpdateResponse.java +++ /dev/null @@ -1,640 +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.atomic; - -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; -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.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheReturn; -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; -import org.apache.ignite.internal.util.GridLongList; -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; -import org.jetbrains.annotations.Nullable; - -/** - * DHT atomic cache near update response. - */ -public class GridNearAtomicMultipleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridNearAtomicUpdateResponse { - /** */ - private static final long serialVersionUID = 0L; - - /** Cache message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID this reply should be sent to. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Update error. */ - @GridDirectTransient - private volatile IgniteCheckedException err; - - /** Serialized error. */ - private byte[] errBytes; - - /** Return value. */ - @GridToStringInclude - private GridCacheReturn ret; - - /** Failed keys. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private volatile Collection failedKeys; - - /** Keys that should be remapped. */ - @GridToStringInclude - @GridDirectCollection(KeyCacheObject.class) - private List remapKeys; - - /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearValsIdxs; - - /** Indexes of keys for which update was skipped (used if originating node has near cache). */ - @GridDirectCollection(int.class) - private List nearSkipIdxs; - - /** Values generated on primary node which should be put to originating node's near cache. */ - @GridToStringInclude - @GridDirectCollection(CacheObject.class) - private List nearVals; - - /** Version generated on primary node to be used for originating node's near cache update. */ - private GridCacheVersion nearVer; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridNearAtomicMultipleUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param nodeId Node ID this reply should be sent to. - * @param futVer Future version. - * @param addDepInfo Deployment info flag. - */ - public GridNearAtomicMultipleUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { - assert futVer != null; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID this response should be sent to. - */ - @Override public UUID nodeId() { - return nodeId; - } - - /** - * @param nodeId Node ID. - */ - @Override public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** - * @return Future version. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - @Override public void error(IgniteCheckedException err){ - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Collection of failed keys. - */ - @Override public Collection failedKeys() { - return failedKeys; - } - - /** - * @return Return value. - */ - @Override public GridCacheReturn returnValue() { - return ret; - } - - /** - * @param ret Return value. - */ - @Override @SuppressWarnings("unchecked") - public void returnValue(GridCacheReturn ret) { - this.ret = ret; - } - - /** - * @param remapKeys Remap keys. - */ - @Override public void remapKeys(List remapKeys) { - this.remapKeys = remapKeys; - } - - /** - * @return Remap keys. - */ - @Override public Collection remapKeys() { - return remapKeys; - } - - /** - * Adds value to be put in near cache on originating node. - * - * @param keyIdx Key index. - * @param val Value. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - @Override public void addNearValue(int keyIdx, - @Nullable CacheObject val, - long ttl, - long expireTime) { - if (nearValsIdxs == null) { - nearValsIdxs = new ArrayList<>(); - nearVals = new ArrayList<>(); - } - - addNearTtl(keyIdx, ttl, expireTime); - - nearValsIdxs.add(keyIdx); - nearVals.add(val); - } - - /** - * @param keyIdx Key index. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - @Override @SuppressWarnings("ForLoopReplaceableByForEach") - public void addNearTtl(int keyIdx, long ttl, long expireTime) { - if (ttl >= 0) { - if (nearTtls == null) { - nearTtls = new GridLongList(16); - - for (int i = 0; i < keyIdx; i++) - nearTtls.add(-1L); - } - } - - if (nearTtls != null) - nearTtls.add(ttl); - - if (expireTime >= 0) { - if (nearExpireTimes == null) { - nearExpireTimes = new GridLongList(16); - - for (int i = 0; i < keyIdx; i++) - nearExpireTimes.add(-1); - } - } - - if (nearExpireTimes != null) - nearExpireTimes.add(expireTime); - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - @Override public long nearExpireTime(int idx) { - if (nearExpireTimes != null) { - assert idx >= 0 && idx < nearExpireTimes.size(); - - return nearExpireTimes.get(idx); - } - - return -1L; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - @Override public long nearTtl(int idx) { - if (nearTtls != null) { - assert idx >= 0 && idx < nearTtls.size(); - - return nearTtls.get(idx); - } - - return -1L; - } - - /** - * @param nearVer Version generated on primary node to be used for originating node's near cache update. - */ - @Override public void nearVersion(GridCacheVersion nearVer) { - this.nearVer = nearVer; - } - - /** - * @return Version generated on primary node to be used for originating node's near cache update. - */ - @Override public GridCacheVersion nearVersion() { - return nearVer; - } - - /** - * @param keyIdx Index of key for which update was skipped - */ - @Override public void addSkippedIndex(int keyIdx) { - if (nearSkipIdxs == null) - nearSkipIdxs = new ArrayList<>(); - - nearSkipIdxs.add(keyIdx); - - addNearTtl(keyIdx, -1L, -1L); - } - - /** - * @return Indexes of keys for which update was skipped - */ - @Override @Nullable public List skippedIndexes() { - return nearSkipIdxs; - } - - /** - * @return Indexes of keys for which values were generated on primary node. - */ - @Override @Nullable public List nearValuesIndexes() { - return nearValsIdxs; - } - - /** - * @param idx Index. - * @return Value generated on primary node which should be put to originating node's near cache. - */ - @Override @Nullable public CacheObject nearValue(int idx) { - return nearVals.get(idx); - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - @Override public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { - if (failedKeys == null) - failedKeys = new ConcurrentLinkedQueue<>(); - - failedKeys.add(key); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - */ - @Override public synchronized void addFailedKeys(Collection keys, Throwable e) { - if (keys != null) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); - - failedKeys.addAll(keys); - } - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - * @param ctx Context. - */ - @Override public synchronized void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx) { - if (failedKeys == null) - failedKeys = new ArrayList<>(keys.size()); - - failedKeys.addAll(keys); - - if (err == null) - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (err != null && errBytes == null) - errBytes = ctx.marshaller().marshal(err); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(failedKeys, cctx); - - prepareMarshalCacheObjects(remapKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); - - if (ret != null) - ret.prepareMarshal(cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - - finishUnmarshalCacheObjects(remapKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearVals, cctx, ldr); - - if (ret != null) - ret.finishUnmarshal(cctx, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeMessage("nearTtls", nearTtls)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("nearVer", nearVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeMessage("ret", ret)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - nearExpireTimes = reader.readMessage("nearExpireTimes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - nearTtls = reader.readMessage("nearTtls"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - nearVer = reader.readMessage("nearVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - ret = reader.readMessage("ret"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridNearAtomicMultipleUpdateResponse.class); - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return 41; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 14; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicMultipleUpdateResponse.class, this, "parent"); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java deleted file mode 100644 index 94a586d90cea6..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ /dev/null @@ -1,898 +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.atomic; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; -import org.apache.ignite.internal.GridDirectTransient; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -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.IgniteExternalizableExpiryPolicy; -import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.CU; -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; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.processor.EntryProcessor; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; -import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; - -/** - * Lite DHT cache update request sent from near node to primary node. - */ -public class GridNearAtomicSingleUpdateRequest extends GridCacheMessage - implements GridNearAtomicUpdateRequest, GridCacheDeployable { - /** */ - private static final long serialVersionUID = 0L; - - /** Message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Target node ID. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Fast map flag. */ - private boolean fastMap; - - /** Update version. Set to non-null if fastMap is {@code true}. */ - private GridCacheVersion updateVer; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ - private boolean topLocked; - - /** Write synchronization mode. */ - private CacheWriteSynchronizationMode syncMode; - - /** Update operation. */ - private GridCacheOperation op; - - /** Key to update. */ - @GridToStringInclude - private KeyCacheObject key; - - /** Value to update. */ - private CacheObject val; - - /** Entry processor. */ - @GridDirectTransient - private EntryProcessor entryProc; - - /** Entry processor bytes. */ - private byte[] entryProcBytes; - - /** Optional arguments for entry processor. */ - @GridDirectTransient - private Object[] invokeArgs; - - /** Entry processor arguments bytes. */ - private byte[][] invokeArgsBytes; - - /** Conflict version. */ - private GridCacheVersion conflictVer; - - /** Conflict TTL. */ - private long conflictTtl = CU.TTL_NOT_CHANGED; - - /** Conflict expire time. */ - private long conflictExpireTime = CU.EXPIRE_TIME_CALCULATE; - - /** Return value flag. */ - private boolean retval; - - /** Expiry policy. */ - @GridDirectTransient - private ExpiryPolicy expiryPlc; - - /** Expiry policy bytes. */ - private byte[] expiryPlcBytes; - - /** Filter. */ - private CacheEntryPredicate[] filter; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Skip write-through to a persistent storage. */ - private boolean skipStore; - - /** */ - private boolean clientReq; - - /** Keep binary flag. */ - private boolean keepBinary; - - /** */ - @GridDirectTransient - private GridNearAtomicUpdateResponse res; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridNearAtomicSingleUpdateRequest() { - // No-op. - } - - /** - * Constructor. - * - * @param key Key. - * @param val Value. - * @param conflictTtl Conflict TTL (optional). - * @param conflictExpireTime Conflict expire time (optional). - * @param conflictVer Conflict version (optional). - * @param cacheId Cache ID. - * @param nodeId Node ID. - * @param futVer Future version. - * @param fastMap Fast map scheme flag. - * @param updateVer Update version set if fast map is performed. - * @param topVer Topology version. - * @param topLocked Topology locked flag. - * @param syncMode Synchronization mode. - * @param op Cache update operation. - * @param retval Return value required flag. - * @param expiryPlc Expiry policy. - * @param invokeArgs Optional arguments for entry processor. - * @param filter Optional filter for atomic check. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param skipStore Skip write-through to a persistent storage. - * @param keepBinary Keep binary flag. - * @param clientReq Client node request flag. - * @param addDepInfo Deployment info flag. - */ - @SuppressWarnings("unchecked") - public GridNearAtomicSingleUpdateRequest( - KeyCacheObject key, - @Nullable Object val, - long conflictTtl, - long conflictExpireTime, - @Nullable GridCacheVersion conflictVer, - int cacheId, - UUID nodeId, - GridCacheVersion futVer, - boolean fastMap, - @Nullable GridCacheVersion updateVer, - @NotNull AffinityTopologyVersion topVer, - boolean topLocked, - CacheWriteSynchronizationMode syncMode, - GridCacheOperation op, - boolean retval, - @Nullable ExpiryPolicy expiryPlc, - @Nullable Object[] invokeArgs, - @Nullable CacheEntryPredicate[] filter, - @Nullable UUID subjId, - int taskNameHash, - boolean skipStore, - boolean keepBinary, - boolean clientReq, - boolean addDepInfo - ) { - assert futVer != null; - - this.key = key; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.fastMap = fastMap; - this.updateVer = updateVer; - - this.topVer = topVer; - this.topLocked = topLocked; - this.syncMode = syncMode; - this.op = op; - this.retval = retval; - this.expiryPlc = expiryPlc; - this.invokeArgs = invokeArgs; - this.filter = filter; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.skipStore = skipStore; - this.keepBinary = keepBinary; - this.clientReq = clientReq; - this.addDepInfo = addDepInfo; - - EntryProcessor entryProc = null; - - if (op == TRANSFORM) { - assert val instanceof EntryProcessor : val; - - entryProc = (EntryProcessor)val; - } - - assert val != null || op == DELETE; - - if (entryProc != null) - this.entryProc = entryProc; - else if (val != null) { - assert val instanceof CacheObject : val; - - this.val = (CacheObject)val; - } - - this.conflictVer = conflictVer; - - if (conflictTtl >= 0) - this.conflictTtl = conflictTtl; - - if (conflictExpireTime >= 0) - this.conflictExpireTime = conflictExpireTime; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** {@inheritDoc} */ - @Override public UUID nodeId() { - return nodeId; - } - - /** {@inheritDoc} */ - @Override public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** {@inheritDoc} */ - @Override public UUID subjectId() { - return subjId; - } - - /** {@inheritDoc} */ - @Override public int taskNameHash() { - return taskNameHash; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** {@inheritDoc} */ - @Override public boolean fastMap() { - return fastMap; - } - - /** {@inheritDoc} */ - @Override public GridCacheVersion updateVersion() { - return updateVer; - } - - /** {@inheritDoc} */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** {@inheritDoc} */ - @Override public boolean topologyLocked() { - return topLocked; - } - - /** {@inheritDoc} */ - @Override public boolean clientRequest() { - return clientReq; - } - - /** {@inheritDoc} */ - @Override public CacheWriteSynchronizationMode writeSynchronizationMode() { - return syncMode; - } - - /** {@inheritDoc} */ - @Override public ExpiryPolicy expiry() { - return expiryPlc; - } - - /** {@inheritDoc} */ - @Override public boolean returnValue() { - return retval; - } - - /** {@inheritDoc} */ - @Override @Nullable public CacheEntryPredicate[] filter() { - return filter; - } - - /** {@inheritDoc} */ - @Override public boolean skipStore() { - return skipStore; - } - - /** {@inheritDoc} */ - @Override public boolean keepBinary() { - return keepBinary; - } - - /** {@inheritDoc} */ - @Override public List keys() { - return Collections.singletonList(key); - } - - /** {@inheritDoc} */ - @Override public List values() { - return Collections.singletonList(op == TRANSFORM ? entryProc : val); - } - - /** {@inheritDoc} */ - @Override public GridCacheOperation operation() { - return op; - } - - /** {@inheritDoc} */ - @Override @Nullable public Object[] invokeArguments() { - return invokeArgs; - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public CacheObject value(int idx) { - assert idx == 0; - assert op == UPDATE : op; - - return val; - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public EntryProcessor entryProcessor(int idx) { - assert idx == 0; - assert op == TRANSFORM : op; - - return entryProc; - } - - /** {@inheritDoc} */ - @Override public CacheObject writeValue(int idx) { - assert idx == 0; - - return val; - } - - /** {@inheritDoc} */ - @Override @Nullable public List conflictVersions() { - return conflictVer == null ? null : Collections.singletonList(conflictVer); - } - - /** {@inheritDoc} */ - @Override @Nullable public GridCacheVersion conflictVersion(int idx) { - assert idx == 0; - - return conflictVer; - } - - /** {@inheritDoc} */ - @Override public long conflictTtl(int idx) { - assert idx == 0; - - return conflictTtl; - } - - /** {@inheritDoc} */ - @Override public long conflictExpireTime(int idx) { - assert idx == 0; - - return conflictExpireTime; - } - - /** {@inheritDoc} */ - @Override public boolean hasPrimary() { - return true; - } - - /** {@inheritDoc} */ - @Override public boolean onResponse(GridNearAtomicUpdateResponse res) { - if (this.res == null) { - this.res = res; - - return true; - } - - return false; - } - - /** {@inheritDoc} */ - @Override @Nullable public GridNearAtomicUpdateResponse response() { - return res; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(key, cctx); - - if (filter != null) { - boolean hasFilter = false; - - for (CacheEntryPredicate p : filter) { - if (p != null) { - hasFilter = true; - - p.prepareMarshal(cctx); - } - } - - if (!hasFilter) - filter = null; - } - - if (expiryPlc != null && expiryPlcBytes == null) - expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); - - if (op == TRANSFORM) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (entryProcBytes == null) - entryProcBytes = marshal(entryProc, cctx); - - if (invokeArgsBytes == null) - invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); - } - else - prepareMarshalCacheObject(val, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObject(key, cctx, ldr); - - if (op == TRANSFORM) { - if (entryProc == null) - entryProc = unmarshal(entryProcBytes, ctx, ldr); - - if (invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); - } - else - finishUnmarshalCacheObject(val, cctx, ldr); - - if (filter != null) { - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - - if (expiryPlcBytes != null && expiryPlc == null) - expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeBoolean("clientReq", clientReq)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeLong("conflictExpireTime", conflictExpireTime)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeLong("conflictTtl", conflictTtl)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeMessage("conflictVer", conflictVer)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeByteArray("entryProcBytes", entryProcBytes)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeBoolean("fastMap", fastMap)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeBoolean("keepBinary", keepBinary)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeMessage("key", key)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 16: - if (!writer.writeBoolean("retval", retval)) - return false; - - writer.incrementState(); - - case 17: - if (!writer.writeBoolean("skipStore", skipStore)) - return false; - - writer.incrementState(); - - case 18: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 19: - if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) - return false; - - writer.incrementState(); - - case 20: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeBoolean("topLocked", topLocked)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeMessage("topVer", topVer)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeMessage("updateVer", updateVer)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeMessage("val", val)) - 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: - clientReq = reader.readBoolean("clientReq"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - conflictExpireTime = reader.readLong("conflictExpireTime"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - conflictTtl = reader.readLong("conflictTtl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - conflictVer = reader.readMessage("conflictVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - entryProcBytes = reader.readByteArray("entryProcBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - fastMap = reader.readBoolean("fastMap"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - keepBinary = reader.readBoolean("keepBinary"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - key = reader.readMessage("key"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - byte opOrd; - - opOrd = reader.readByte("op"); - - if (!reader.isLastRead()) - return false; - - op = GridCacheOperation.fromOrdinal(opOrd); - - reader.incrementState(); - - case 16: - retval = reader.readBoolean("retval"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 17: - skipStore = reader.readBoolean("skipStore"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 18: - subjId = reader.readUuid("subjId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 19: - byte syncModeOrd; - - syncModeOrd = reader.readByte("syncMode"); - - if (!reader.isLastRead()) - return false; - - syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); - - reader.incrementState(); - - case 20: - taskNameHash = reader.readInt("taskNameHash"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 21: - topLocked = reader.readBoolean("topLocked"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - topVer = reader.readMessage("topVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - updateVer = reader.readMessage("updateVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - val = reader.readMessage("val"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridNearAtomicSingleUpdateRequest.class); - } - - @Override public void cleanup(boolean clearKeys) { - val = null; - entryProc = null; - entryProcBytes = null; - invokeArgs = null; - invokeArgsBytes = null; - - if (clearKeys) - key = null; - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return -23; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 25; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicSingleUpdateRequest.class, this, "filter", Arrays.toString(filter), - "parent", super.toString()); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java deleted file mode 100644 index d6eabd40adc92..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateResponse.java +++ /dev/null @@ -1,614 +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.atomic; - -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.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheReturn; -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; -import org.apache.ignite.internal.util.GridLongList; -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; -import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; -import org.jetbrains.annotations.Nullable; - -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public class GridNearAtomicSingleUpdateResponse extends GridCacheMessage implements GridCacheDeployable, GridNearAtomicUpdateResponse { - - /** */ - private static final long serialVersionUID = 0L; - - /** Cache message index. */ - public static final int CACHE_MSG_IDX = nextIndexId(); - - /** Node ID this reply should be sent to. */ - @GridDirectTransient - private UUID nodeId; - - /** Future version. */ - private GridCacheVersion futVer; - - /** Update error. */ - @GridDirectTransient - private volatile IgniteCheckedException err; - - /** Serialized error. */ - private byte[] errBytes; - - /** Return value. */ - @GridToStringInclude - private GridCacheReturn ret; - - private KeyCacheObject key; - - private boolean failed; - - private boolean remap; - - private boolean hasNearVal; - - private CacheObject nearVal; - - private boolean nearSkip; - - private long nearTtl = -1; - - private long nearExpireTime = -1; - - /** Version generated on primary node to be used for originating node's near cache update. */ - private GridCacheVersion nearVer; - - /** Near TTLs. */ - private GridLongList nearTtls; - - /** Near expire times. */ - private GridLongList nearExpireTimes; - - /** - * Empty constructor required by {@link Externalizable}. - */ - public GridNearAtomicSingleUpdateResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param nodeId Node ID this reply should be sent to. - * @param futVer Future version. - * @param addDepInfo Deployment info flag. - */ - public GridNearAtomicSingleUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { - assert futVer != null; - - this.cacheId = cacheId; - this.nodeId = nodeId; - this.futVer = futVer; - this.addDepInfo = addDepInfo; - } - - /** {@inheritDoc} */ - @Override public int lookupIndex() { - return CACHE_MSG_IDX; - } - - /** - * @return Node ID this response should be sent to. - */ - @Override public UUID nodeId() { - return nodeId; - } - - /** - * @param nodeId Node ID. - */ - @Override public void nodeId(UUID nodeId) { - this.nodeId = nodeId; - } - - /** - * @return Future version. - */ - @Override public GridCacheVersion futureVersion() { - return futVer; - } - - /** - * Sets update error. - * - * @param err Error. - */ - @Override public void error(IgniteCheckedException err) { - this.err = err; - } - - /** {@inheritDoc} */ - @Override public IgniteCheckedException error() { - return err; - } - - /** - * @return Collection of failed keys. - */ - @Override public Collection failedKeys() { - if (failed && key != null) - return Collections.singletonList(key); - - return null; - } - - /** - * @return Return value. - */ - @Override public GridCacheReturn returnValue() { - return ret; - } - - /** - * @param ret Return value. - */ - @Override @SuppressWarnings("unchecked") - public void returnValue(GridCacheReturn ret) { - this.ret = ret; - } - - /** - * @param remapKeys Remap keys. - */ - @Override public void remapKeys(List remapKeys) { - assert remapKeys.size() <= 1; - - if (remapKeys.isEmpty()) - return; - - key = remapKeys.get(0); - remap = true; - } - - /** - * @return Remap keys. - */ - @Override public Collection remapKeys() { - if (remap && key != null) - return Collections.singletonList(key); - - return null; - } - - /** - * Adds value to be put in near cache on originating node. - * - * @param keyIdx Key index. - * @param val Value. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - @Override public void addNearValue(int keyIdx, - @Nullable CacheObject val, - long ttl, - long expireTime) { - - assert keyIdx == 0; - - nearVal = val; - hasNearVal = true; - - addNearTtl(keyIdx, ttl, expireTime); - } - - /** - * @param keyIdx Key index. - * @param ttl TTL for near cache update. - * @param expireTime Expire time for near cache update. - */ - @Override @SuppressWarnings("ForLoopReplaceableByForEach") - public void addNearTtl(int keyIdx, long ttl, long expireTime) { - assert keyIdx == 0; - - nearTtl = ttl >= 0 ? ttl : -1; - - nearExpireTime = expireTime >= 0 ? expireTime : -1; - } - - /** - * @param idx Index. - * @return Expire time for near cache update. - */ - @Override public long nearExpireTime(int idx) { - if (idx == 0) - return nearExpireTime; - - return -1L; - } - - /** - * @param idx Index. - * @return TTL for near cache update. - */ - @Override public long nearTtl(int idx) { - if (idx == 0) - return nearTtl; - - return -1L; - } - - /** - * @param nearVer Version generated on primary node to be used for originating node's near cache update. - */ - @Override public void nearVersion(GridCacheVersion nearVer) { - this.nearVer = nearVer; - } - - /** - * @return Version generated on primary node to be used for originating node's near cache update. - */ - @Override public GridCacheVersion nearVersion() { - return nearVer; - } - - /** - * @param keyIdx Index of key for which update was skipped - */ - @Override public void addSkippedIndex(int keyIdx) { - assert keyIdx == 0; - - nearSkip = true; - nearTtl = -1; - nearExpireTime = -1; - } - - /** - * @return Indexes of keys for which update was skipped - */ - @Override @Nullable public List skippedIndexes() { - if (nearSkip) - return Collections.singletonList(0); - - return null; - } - - /** - * @return Indexes of keys for which values were generated on primary node. - */ - @Override @Nullable public List nearValuesIndexes() { - if (hasNearVal) - return Collections.singletonList(0); - - return null; - } - - /** - * @param idx Index. - * @return Value generated on primary node which should be put to originating node's near cache. - */ - @Override @Nullable public CacheObject nearValue(int idx) { - assert idx == 0; - - if (hasNearVal) - return nearVal; - - return null; - } - - /** - * Adds key to collection of failed keys. - * - * @param key Key to add. - * @param e Error cause. - */ - @Override public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { - this.key = key; - failed = true; - - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - */ - @Override public synchronized void addFailedKeys(Collection keys, Throwable e) { - if (keys != null) { - assert keys.size() <= 1; - - if (keys.size() == 1) - key = F.first(keys); - } - - err = new IgniteCheckedException("Failed to update keys on primary node."); - - err.addSuppressed(e); - } - - /** - * Adds keys to collection of failed keys. - * - * @param keys Key to add. - * @param e Error cause. - * @param ctx Context. - */ - @Override public synchronized void addFailedKeys(Collection keys, Throwable e, - GridCacheContext ctx) { - addFailedKeys(keys, e); - } - - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (err != null && errBytes == null) - errBytes = ctx.marshaller().marshal(err); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(key, cctx); - - prepareMarshalCacheObject(nearVal, cctx); - - if (ret != null) - ret.prepareMarshal(cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (errBytes != null && err == null) - err = ctx.marshaller().unmarshal(errBytes, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObject(key, cctx, ldr); - - finishUnmarshalCacheObject(nearVal, cctx, ldr); - - if (ret != null) - ret.finishUnmarshal(cctx, ldr); - } - - /** {@inheritDoc} */ - @Override public boolean addDeploymentInfo() { - return addDepInfo; - } - - /** {@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.writeByteArray("errBytes", errBytes)) - return false; - - writer.incrementState(); - - case 4: - if (!writer.writeBoolean("failed", failed)) - return false; - - writer.incrementState(); - - case 5: - if (!writer.writeMessage("futVer", futVer)) - return false; - - writer.incrementState(); - - case 6: - if (!writer.writeLong("nearExpireTime", nearExpireTime)) - return false; - - writer.incrementState(); - - case 7: - if (!writer.writeBoolean("nearSkip", nearSkip)) - return false; - - writer.incrementState(); - - case 8: - if (!writer.writeLong("nearTtl", nearTtl)) - return false; - - writer.incrementState(); - - case 9: - if (!writer.writeMessage("nearVal", nearVal)) - return false; - - writer.incrementState(); - - case 10: - if (!writer.writeBoolean("hasNearVal", hasNearVal)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeMessage("nearVer", nearVer)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeMessage("key", key)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeMessage("ret", ret)) - 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: - errBytes = reader.readByteArray("errBytes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 4: - failed = reader.readBoolean("failed"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 5: - futVer = reader.readMessage("futVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 6: - nearExpireTime = reader.readLong("nearExpireTime"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 7: - nearSkip = reader.readBoolean("nearSkip"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 8: - nearTtl = reader.readLong("nearTtl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 9: - nearVal = reader.readMessage("nearVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 10: - hasNearVal = reader.readBoolean("hasNearVal"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - nearVer = reader.readMessage("nearVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - key = reader.readMessage("key"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - ret = reader.readMessage("ret"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - } - - return reader.afterMessageRead(GridNearAtomicSingleUpdateResponse.class); - } - - /** {@inheritDoc} */ - @Override public byte directType() { - return -24; - } - - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 14; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearAtomicSingleUpdateResponse.class, this, "parent"); - } - -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 8edd0d476e05d..519df178c8410 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -38,7 +38,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; import org.apache.ignite.internal.processors.cache.GridCacheAtomicFuture; import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccManager; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheReturn; @@ -58,7 +57,6 @@ 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.IgniteProductVersion; import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; @@ -71,10 +69,8 @@ /** * DHT atomic cache near update future. */ -public class GridNearAtomicUpdateFuture extends GridFutureAdapter implements GridCacheAtomicFuture { - /** Version where single-put optimization appeared.*/ - public static final IgniteProductVersion SINGLE_PUT_MSG_SINCE = IgniteProductVersion.fromString("1.6.0"); - +public class GridNearAtomicUpdateFuture extends GridFutureAdapter + implements GridCacheAtomicFuture{ /** Logger reference. */ private static final AtomicReference logRef = new AtomicReference<>(); @@ -255,6 +251,11 @@ private boolean waitForPartitionExchange() { return fastMap; } + /** {@inheritDoc} */ + @Override public Collection keys() { + return keys; + } + /** {@inheritDoc} */ @Override public boolean onNodeLeft(UUID nodeId) { state.onNodeLeft(nodeId); @@ -455,8 +456,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (cctx.localNodeId().equals(nodeId)) { cache.updateAllAsyncInternal(nodeId, req, new CI2() { - @Override public void apply(GridNearAtomicUpdateRequest req, - GridNearAtomicUpdateResponse res) { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -466,7 +466,7 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { if (log.isDebugEnabled()) log.debug("Sending near atomic update request [nodeId=" + req.nodeId() + ", req=" + req + ']'); - cctx.io().send(req.nodeId(), (GridCacheMessage)req, cctx.ioPolicy()); + cctx.io().send(req.nodeId(), req, cctx.ioPolicy()); if (syncMode == FULL_ASYNC) onDone(new GridCacheReturn(cctx, true, true, null, true)); @@ -482,13 +482,13 @@ private void mapSingle(UUID nodeId, GridNearAtomicUpdateRequest req) { * * @param mappings Mappings to send. */ - private void doUpdate(Map mappings) { + private void doUpdate(Map mappings) { UUID locNodeId = cctx.localNodeId(); - GridNearAtomicMultipleUpdateRequest locUpdate = null; + GridNearAtomicUpdateRequest locUpdate = null; // Send messages to remote nodes first, then run local update. - for (GridNearAtomicMultipleUpdateRequest req : mappings.values()) { + for (GridNearAtomicUpdateRequest req : mappings.values()) { if (locNodeId.equals(req.nodeId())) { assert locUpdate == null : "Cannot have more than one local mapping [locUpdate=" + locUpdate + ", req=" + req + ']'; @@ -510,9 +510,8 @@ private void doUpdate(Map mappings) { if (locUpdate != null) { cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, - new CI2() { - @Override public void apply(GridNearAtomicMultipleUpdateRequest req, - GridNearAtomicMultipleUpdateResponse res) { + new CI2() { + @Override public void apply(GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { onResult(res.nodeId(), res); } }); @@ -537,7 +536,7 @@ private class UpdateState { /** Mappings if operations is mapped to more than one node. */ @GridToStringInclude - private Map mappings; + private Map mappings; /** */ private int resCnt; @@ -582,16 +581,10 @@ void onNodeLeft(UUID nodeId) { req = mappings != null ? mappings.get(nodeId) : null; if (req != null && req.response() == null) { - if (req instanceof GridNearAtomicSingleUpdateRequest) - res = new GridNearAtomicSingleUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); - else - res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), - nodeId, - req.futureVersion(), - cctx.deploymentEnabled()); + res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + nodeId, + req.futureVersion(), + cctx.deploymentEnabled()); ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " + "before response is received: " + nodeId); @@ -611,8 +604,8 @@ void onNodeLeft(UUID nodeId) { * @param res Response. * @param nodeErr {@code True} if response was created on node failure. */ - @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) void onResult(UUID nodeId, - GridNearAtomicUpdateResponse res, boolean nodeErr) { + @SuppressWarnings("unchecked") + void onResult(UUID nodeId, GridNearAtomicUpdateResponse res, boolean nodeErr) { GridNearAtomicUpdateRequest req; AffinityTopologyVersion remapTopVer = null; @@ -743,7 +736,7 @@ else if (res.error() != null) { if (rcvAll && nearEnabled) { if (mappings != null) { - for (GridNearAtomicMultipleUpdateRequest req0 : mappings.values()) { + for (GridNearAtomicUpdateRequest req0 : mappings.values()) { GridNearAtomicUpdateResponse res0 = req0.response(); assert res0 != null : req0; @@ -819,18 +812,10 @@ else if (!nodeErr) */ void onSendError(GridNearAtomicUpdateRequest req, IgniteCheckedException e) { synchronized (this) { - GridNearAtomicUpdateResponse res; - - if (req instanceof GridNearAtomicSingleUpdateRequest) - res = new GridNearAtomicSingleUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); - else - res = new GridNearAtomicMultipleUpdateResponse(cctx.cacheId(), - req.nodeId(), - req.futureVersion(), - cctx.deploymentEnabled()); + GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(), + req.nodeId(), + req.futureVersion(), + cctx.deploymentEnabled()); res.addFailedKeys(req.keys(), e); @@ -854,7 +839,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re Exception err = null; GridNearAtomicUpdateRequest singleReq0 = null; - Map mappings0 = null; + Map mappings0 = null; int size = keys.size(); @@ -880,10 +865,10 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re if (size == 1 && !fastMap) { assert remapKeys == null || remapKeys.size() == 1; - singleReq0 = mapSingleUpdate(topVer, topNodes, futVer, updVer); + singleReq0 = mapSingleUpdate(topVer, futVer, updVer); } else { - Map pendingMappings = mapUpdate(topNodes, + Map pendingMappings = mapUpdate(topNodes, topVer, futVer, updVer, @@ -895,7 +880,7 @@ void map(AffinityTopologyVersion topVer, @Nullable Collection re if (syncMode == PRIMARY_SYNC) { mappings0 = U.newHashMap(pendingMappings.size()); - for (GridNearAtomicMultipleUpdateRequest req : pendingMappings.values()) { + for (GridNearAtomicUpdateRequest req : pendingMappings.values()) { if (req.hasPrimary()) mappings0.put(req.nodeId(), req); } @@ -1005,8 +990,7 @@ GridCacheVersion onFutureDone() { * @return Mapping. * @throws Exception If failed. */ - @SuppressWarnings("ConstantConditions") - private Map mapUpdate(Collection topNodes, + private Map mapUpdate(Collection topNodes, AffinityTopologyVersion topVer, GridCacheVersion futVer, @Nullable GridCacheVersion updVer, @@ -1026,7 +1010,7 @@ private Map mapUpdate(Collection pendingMappings = U.newHashMap(topNodes.size()); + Map pendingMappings = U.newHashMap(topNodes.size()); // Create mappings first, then send messages. for (Object key : keys) { @@ -1052,7 +1036,7 @@ else if (conflictPutVals != null) { val = conflictPutVal.valueEx(); conflictVer = conflictPutVal.version(); - conflictTtl = conflictPutVal.ttl(); + conflictTtl = conflictPutVal.ttl(); conflictExpireTime = conflictPutVal.expireTime(); } else if (conflictRmvVals != null) { @@ -1094,10 +1078,10 @@ else if (conflictRmvVals != null) { UUID nodeId = affNode.id(); - GridNearAtomicMultipleUpdateRequest mapped = pendingMappings.get(nodeId); + GridNearAtomicUpdateRequest mapped = pendingMappings.get(nodeId); if (mapped == null) { - mapped = new GridNearAtomicMultipleUpdateRequest( + mapped = new GridNearAtomicUpdateRequest( cctx.cacheId(), nodeId, futVer, @@ -1139,8 +1123,8 @@ else if (conflictRmvVals != null) { * @throws Exception If failed. */ private GridNearAtomicUpdateRequest mapSingleUpdate(AffinityTopologyVersion topVer, - Collection topNodes, GridCacheVersion futVer, @Nullable GridCacheVersion updVer) - throws Exception { + GridCacheVersion futVer, + @Nullable GridCacheVersion updVer) throws Exception { Object key = F.first(keys); Object val; @@ -1197,76 +1181,36 @@ else if (conflictRmvVals != null) { throw new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all partition nodes " + "left the grid)."); - // Decide whether we will use optimzied version of update request. - boolean optimize = true; - - for (ClusterNode topNode : topNodes) { - if (topNode.version().compareTo(SINGLE_PUT_MSG_SINCE) < 0) { - optimize = false; - - break; - } - } - - if (optimize) { - return new GridNearAtomicSingleUpdateRequest( - cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled()); - } - else { - GridNearAtomicMultipleUpdateRequest req = new GridNearAtomicMultipleUpdateRequest( - cctx.cacheId(), - primary.id(), - futVer, - fastMap, - updVer, - topVer, - topLocked, - syncMode, - op, - retval, - expiryPlc, - invokeArgs, - filter, - subjId, - taskNameHash, - skipStore, - keepBinary, - cctx.kernalContext().clientNode(), - cctx.deploymentEnabled(), - 1); - - req.addUpdateEntry(cacheKey, - val, - conflictTtl, - conflictExpireTime, - conflictVer, - true); - - return req; - } + GridNearAtomicUpdateRequest req = new GridNearAtomicUpdateRequest( + cctx.cacheId(), + primary.id(), + futVer, + fastMap, + updVer, + topVer, + topLocked, + syncMode, + op, + retval, + expiryPlc, + invokeArgs, + filter, + subjId, + taskNameHash, + skipStore, + keepBinary, + cctx.kernalContext().clientNode(), + cctx.deploymentEnabled(), + 1); + + req.addUpdateEntry(cacheKey, + val, + conflictTtl, + conflictExpireTime, + conflictVer, + true); + + return req; } /** @@ -1307,7 +1251,7 @@ private void addFailedKeys(Collection failedKeys, } /** {@inheritDoc} */ - @Override public synchronized String toString() { + @Override public synchronized String toString() { return S.toString(UpdateState.class, this); } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index bf935593469de..0f97e599b3b7e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -17,190 +17,1042 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import javax.cache.expiry.ExpiryPolicy; +import javax.cache.processor.EntryProcessor; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; 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.IgniteExternalizableExpiryPolicy; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.CU; +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; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.cache.expiry.ExpiryPolicy; -import javax.cache.processor.EntryProcessor; -import java.util.List; -import java.util.UUID; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM; +import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE; /** - * Base interface for near atomic update requests. + * Lite DHT cache update request sent from near node to primary node. */ -public interface GridNearAtomicUpdateRequest { +public class GridNearAtomicUpdateRequest extends GridCacheMessage implements GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Target node ID. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Fast map flag. */ + private boolean fastMap; + + /** Update version. Set to non-null if fastMap is {@code true}. */ + private GridCacheVersion updateVer; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Topology locked flag. Set if atomic update is performed inside TX or explicit lock. */ + private boolean topLocked; + + /** Write synchronization mode. */ + private CacheWriteSynchronizationMode syncMode; + + /** Update operation. */ + private GridCacheOperation op; + + /** Keys to update. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List keys; + + /** Values to update. */ + @GridDirectCollection(CacheObject.class) + private List vals; + + /** Entry processors. */ + @GridDirectTransient + private List> entryProcessors; + + /** Entry processors bytes. */ + @GridDirectCollection(byte[].class) + private List entryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + + /** Conflict versions. */ + @GridDirectCollection(GridCacheVersion.class) + private List conflictVers; + + /** Conflict TTLs. */ + private GridLongList conflictTtls; + + /** Conflict expire times. */ + private GridLongList conflictExpireTimes; + + /** Return value flag. */ + private boolean retval; + + /** Expiry policy. */ + @GridDirectTransient + private ExpiryPolicy expiryPlc; + + /** Expiry policy bytes. */ + private byte[] expiryPlcBytes; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Flag indicating whether request contains primary keys. */ + private boolean hasPrimary; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Skip write-through to a persistent storage. */ + private boolean skipStore; + + /** */ + private boolean clientReq; + + /** Keep binary flag. */ + private boolean keepBinary; + + /** */ + @GridDirectTransient + private GridNearAtomicUpdateResponse res; + + /** Maximum possible size of inner collections. */ + @GridDirectTransient + private int initSize; + /** - * @return Message ID. + * Empty constructor required by {@link Externalizable}. */ - public long messageId(); + public GridNearAtomicUpdateRequest() { + // No-op. + } + + /** + * Constructor. + * + * @param cacheId Cache ID. + * @param nodeId Node ID. + * @param futVer Future version. + * @param fastMap Fast map scheme flag. + * @param updateVer Update version set if fast map is performed. + * @param topVer Topology version. + * @param topLocked Topology locked flag. + * @param syncMode Synchronization mode. + * @param op Cache update operation. + * @param retval Return value required flag. + * @param expiryPlc Expiry policy. + * @param invokeArgs Optional arguments for entry processor. + * @param filter Optional filter for atomic check. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param skipStore Skip write-through to a persistent storage. + * @param keepBinary Keep binary flag. + * @param clientReq Client node request flag. + * @param addDepInfo Deployment info flag. + * @param maxEntryCnt Maximum entries count. + */ + public GridNearAtomicUpdateRequest( + int cacheId, + UUID nodeId, + GridCacheVersion futVer, + boolean fastMap, + @Nullable GridCacheVersion updateVer, + @NotNull AffinityTopologyVersion topVer, + boolean topLocked, + CacheWriteSynchronizationMode syncMode, + GridCacheOperation op, + boolean retval, + @Nullable ExpiryPolicy expiryPlc, + @Nullable Object[] invokeArgs, + @Nullable CacheEntryPredicate[] filter, + @Nullable UUID subjId, + int taskNameHash, + boolean skipStore, + boolean keepBinary, + boolean clientReq, + boolean addDepInfo, + int maxEntryCnt + ) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.fastMap = fastMap; + this.updateVer = updateVer; + + this.topVer = topVer; + this.topLocked = topLocked; + this.syncMode = syncMode; + this.op = op; + this.retval = retval; + this.expiryPlc = expiryPlc; + this.invokeArgs = invokeArgs; + this.filter = filter; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.skipStore = skipStore; + this.keepBinary = keepBinary; + this.clientReq = clientReq; + this.addDepInfo = addDepInfo; + + // By default ArrayList expands to array of 10 elements on first add. We cannot guess how many entries + // will be added to request because of unknown affinity distribution. However, we DO KNOW how many keys + // participate in request. As such, we know upper bound of all collections in request. If this bound is lower + // than 10, we use it. + initSize = Math.min(maxEntryCnt, 10); + + keys = new ArrayList<>(initSize); + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } /** * @return Mapped node ID. */ - public UUID nodeId(); + public UUID nodeId() { + return nodeId; + } /** * @param nodeId Node ID. */ - public void nodeId(UUID nodeId); + public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } /** * @return Subject ID. */ - public UUID subjectId(); + public UUID subjectId() { + return subjId; + } /** * @return Task name hash. */ - public int taskNameHash(); + public int taskNameHash() { + return taskNameHash; + } /** * @return Future version. */ - public GridCacheVersion futureVersion(); + public GridCacheVersion futureVersion() { + return futVer; + } /** * @return Flag indicating whether this is fast-map udpate. */ - public boolean fastMap(); + public boolean fastMap() { + return fastMap; + } /** * @return Update version for fast-map request. */ - public GridCacheVersion updateVersion(); + public GridCacheVersion updateVersion() { + return updateVer; + } /** * @return Topology version. */ - public AffinityTopologyVersion topologyVersion(); + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } /** * @return Topology locked flag. */ - public boolean topologyLocked(); + public boolean topologyLocked() { + return topLocked; + } /** * @return {@code True} if request sent from client node. */ - public boolean clientRequest(); + public boolean clientRequest() { + return clientReq; + } /** * @return Cache write synchronization mode. */ - public CacheWriteSynchronizationMode writeSynchronizationMode(); + public CacheWriteSynchronizationMode writeSynchronizationMode() { + return syncMode; + } /** * @return Expiry policy. */ - public ExpiryPolicy expiry(); + public ExpiryPolicy expiry() { + return expiryPlc; + } /** * @return Return value flag. */ - public boolean returnValue(); + public boolean returnValue() { + return retval; + } /** * @return Filter. */ - @Nullable public CacheEntryPredicate[] filter(); + @Nullable public CacheEntryPredicate[] filter() { + return filter; + } /** * @return Skip write-through to a persistent storage. */ - public boolean skipStore(); + public boolean skipStore() { + return skipStore; + } /** * @return Keep binary flag. */ - public boolean keepBinary(); + public boolean keepBinary() { + return keepBinary; + } + + /** + * @param key Key to add. + * @param val Optional update value. + * @param conflictTtl Conflict TTL (optional). + * @param conflictExpireTime Conflict expire time (optional). + * @param conflictVer Conflict version (optional). + * @param primary If given key is primary on this mapping. + */ + public void addUpdateEntry(KeyCacheObject key, + @Nullable Object val, + long conflictTtl, + long conflictExpireTime, + @Nullable GridCacheVersion conflictVer, + boolean primary) { + EntryProcessor entryProcessor = null; + + if (op == TRANSFORM) { + assert val instanceof EntryProcessor : val; + + entryProcessor = (EntryProcessor) val; + } + + assert val != null || op == DELETE; + + keys.add(key); + + if (entryProcessor != null) { + if (entryProcessors == null) + entryProcessors = new ArrayList<>(initSize); + + entryProcessors.add(entryProcessor); + } + else if (val != null) { + assert val instanceof CacheObject : val; + + if (vals == null) + vals = new ArrayList<>(initSize); + + vals.add((CacheObject)val); + } + + hasPrimary |= primary; + + // In case there is no conflict, do not create the list. + if (conflictVer != null) { + if (conflictVers == null) { + conflictVers = new ArrayList<>(initSize); + + for (int i = 0; i < keys.size() - 1; i++) + conflictVers.add(null); + } + + conflictVers.add(conflictVer); + } + else if (conflictVers != null) + conflictVers.add(null); + + if (conflictTtl >= 0) { + if (conflictTtls == null) { + conflictTtls = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictTtls.add(CU.TTL_NOT_CHANGED); + } + + conflictTtls.add(conflictTtl); + } + + if (conflictExpireTime >= 0) { + if (conflictExpireTimes == null) { + conflictExpireTimes = new GridLongList(keys.size()); + + for (int i = 0; i < keys.size() - 1; i++) + conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE); + } + + conflictExpireTimes.add(conflictExpireTime); + } + } /** * @return Keys for this update request. */ - public List keys(); + public List keys() { + return keys; + } /** * @return Values for this update request. */ - public List values(); + public List values() { + return op == TRANSFORM ? entryProcessors : vals; + } /** * @return Update operation. */ - public GridCacheOperation operation(); + public GridCacheOperation operation() { + return op; + } /** * @return Optional arguments for entry processor. */ - @Nullable public Object[] invokeArguments(); + @Nullable public Object[] invokeArguments() { + return invokeArgs; + } /** * @param idx Key index. * @return Value. */ - public CacheObject value(int idx); + @SuppressWarnings("unchecked") + public CacheObject value(int idx) { + assert op == UPDATE : op; + + return vals.get(idx); + } /** * @param idx Key index. * @return Entry processor. */ - public EntryProcessor entryProcessor(int idx); + @SuppressWarnings("unchecked") + public EntryProcessor entryProcessor(int idx) { + assert op == TRANSFORM : op; + + return entryProcessors.get(idx); + } /** * @param idx Index to get. * @return Write value - either value, or transform closure. */ - public CacheObject writeValue(int idx); + public CacheObject writeValue(int idx) { + if (vals != null) + return vals.get(idx); + + return null; + } /** * @return Conflict versions. */ - @Nullable public List conflictVersions(); + @Nullable public List conflictVersions() { + return conflictVers; + } /** * @param idx Index. * @return Conflict version. */ - @Nullable public GridCacheVersion conflictVersion(int idx); + @Nullable public GridCacheVersion conflictVersion(int idx) { + if (conflictVers != null) { + assert idx >= 0 && idx < conflictVers.size(); + + return conflictVers.get(idx); + } + + return null; + } /** * @param idx Index. * @return Conflict TTL. */ - public long conflictTtl(int idx); + public long conflictTtl(int idx) { + if (conflictTtls != null) { + assert idx >= 0 && idx < conflictTtls.size(); + + return conflictTtls.get(idx); + } + + return CU.TTL_NOT_CHANGED; + } /** * @param idx Index. * @return Conflict expire time. */ - public long conflictExpireTime(int idx); + public long conflictExpireTime(int idx) { + if (conflictExpireTimes != null) { + assert idx >= 0 && idx < conflictExpireTimes.size(); + + return conflictExpireTimes.get(idx); + } + + return CU.EXPIRE_TIME_CALCULATE; + } /** * @return Flag indicating whether this request contains primary keys. */ - public boolean hasPrimary(); + public boolean hasPrimary() { + return hasPrimary; + } /** * @param res Response. * @return {@code True} if current response was {@code null}. */ - public boolean onResponse(GridNearAtomicUpdateResponse res); + public boolean onResponse(GridNearAtomicUpdateResponse res) { + if (this.res == null) { + this.res = res; + + return true; + } + + return false; + } /** * @return Response. */ - @Nullable public GridNearAtomicUpdateResponse response(); + @Nullable public GridNearAtomicUpdateResponse response() { + return res; + } + + /** {@inheritDoc} + * @param ctx*/ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + prepareMarshalCacheObjects(keys, cctx); + + if (filter != null) { + boolean hasFilter = false; + + for (CacheEntryPredicate p : filter) { + if (p != null) { + hasFilter = true; + + p.prepareMarshal(cctx); + } + } + + if (!hasFilter) + filter = null; + } + + if (expiryPlc != null && expiryPlcBytes == null) + expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); + + if (op == TRANSFORM) { + // force addition of deployment info for entry processors if P2P is enabled globally. + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + + if (entryProcessorsBytes == null) + entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + + if (invokeArgsBytes == null) + invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx); + } + else + prepareMarshalCacheObjects(vals, cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(keys, cctx, ldr); + + if (op == TRANSFORM) { + if (entryProcessors == null) + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + if (invokeArgs == null) + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + } + else + finishUnmarshalCacheObjects(vals, cctx, ldr); + + if (filter != null) { + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + + if (expiryPlcBytes != null && expiryPlc == null) + expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeBoolean("clientReq", clientReq)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeMessage("conflictExpireTimes", conflictExpireTimes)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("conflictTtls", conflictTtls)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeCollection("conflictVers", conflictVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("entryProcessorsBytes", entryProcessorsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeByteArray("expiryPlcBytes", expiryPlcBytes)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeBoolean("fastMap", fastMap)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBoolean("hasPrimary", hasPrimary)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("invokeArgsBytes", invokeArgsBytes, MessageCollectionItemType.BYTE_ARR)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeBoolean("keepBinary", keepBinary)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("keys", keys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeByte("op", op != null ? (byte)op.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeBoolean("retval", retval)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeBoolean("skipStore", skipStore)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeBoolean("topLocked", topLocked)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeMessage("topVer", topVer)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeMessage("updateVer", updateVer)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG)) + 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: + clientReq = reader.readBoolean("clientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + conflictExpireTimes = reader.readMessage("conflictExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + conflictTtls = reader.readMessage("conflictTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + conflictVers = reader.readCollection("conflictVers", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + entryProcessorsBytes = reader.readCollection("entryProcessorsBytes", MessageCollectionItemType.BYTE_ARR); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + expiryPlcBytes = reader.readByteArray("expiryPlcBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + fastMap = reader.readBoolean("fastMap"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + hasPrimary = reader.readBoolean("hasPrimary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + invokeArgsBytes = reader.readObjectArray("invokeArgsBytes", MessageCollectionItemType.BYTE_ARR, byte[].class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + keepBinary = reader.readBoolean("keepBinary"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + keys = reader.readCollection("keys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + byte opOrd; + + opOrd = reader.readByte("op"); + + if (!reader.isLastRead()) + return false; + + op = GridCacheOperation.fromOrdinal(opOrd); + + reader.incrementState(); + + case 17: + retval = reader.readBoolean("retval"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + skipStore = reader.readBoolean("skipStore"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 19: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + byte syncModeOrd; + + syncModeOrd = reader.readByte("syncMode"); + + if (!reader.isLastRead()) + return false; + + syncMode = CacheWriteSynchronizationMode.fromOrdinal(syncModeOrd); + + reader.incrementState(); + + case 21: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + topLocked = reader.readBoolean("topLocked"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + updateVer = reader.readMessage("updateVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + vals = reader.readCollection("vals", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearAtomicUpdateRequest.class); + } /** * Cleanup values. * * @param clearKeys If {@code true} clears keys. */ - void cleanup(boolean clearKeys); + public void cleanup(boolean clearKeys) { + vals = null; + entryProcessors = null; + entryProcessorsBytes = null; + invokeArgs = null; + invokeArgsBytes = null; + + if (clearKeys) + keys = null; + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 40; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 26; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicUpdateRequest.class, this, "filter", Arrays.toString(filter), + "parent", super.toString()); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java index 51d388c41b06b..3e3ac29c09e28 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java @@ -17,86 +17,624 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; 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.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheReturn; 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; +import org.apache.ignite.internal.util.GridLongList; +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; import org.jetbrains.annotations.Nullable; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.List; -import java.util.UUID; +/** + * DHT atomic cache near update response. + */ +public class GridNearAtomicUpdateResponse extends GridCacheMessage implements GridCacheDeployable { + /** */ + private static final long serialVersionUID = 0L; + + /** Cache message index. */ + public static final int CACHE_MSG_IDX = nextIndexId(); + + /** Node ID this reply should be sent to. */ + @GridDirectTransient + private UUID nodeId; + + /** Future version. */ + private GridCacheVersion futVer; + + /** Update error. */ + @GridDirectTransient + private volatile IgniteCheckedException err; + + /** Serialized error. */ + private byte[] errBytes; + + /** Return value. */ + @GridToStringInclude + private GridCacheReturn ret; + + /** Failed keys. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private volatile Collection failedKeys; + + /** Keys that should be remapped. */ + @GridToStringInclude + @GridDirectCollection(KeyCacheObject.class) + private List remapKeys; + + /** Indexes of keys for which values were generated on primary node (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearValsIdxs; + + /** Indexes of keys for which update was skipped (used if originating node has near cache). */ + @GridDirectCollection(int.class) + private List nearSkipIdxs; + + /** Values generated on primary node which should be put to originating node's near cache. */ + @GridToStringInclude + @GridDirectCollection(CacheObject.class) + private List nearVals; + + /** Version generated on primary node to be used for originating node's near cache update. */ + private GridCacheVersion nearVer; + + /** Near TTLs. */ + private GridLongList nearTtls; + + /** Near expire times. */ + private GridLongList nearExpireTimes; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public GridNearAtomicUpdateResponse() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param nodeId Node ID this reply should be sent to. + * @param futVer Future version. + * @param addDepInfo Deployment info flag. + */ + public GridNearAtomicUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) { + assert futVer != null; + + this.cacheId = cacheId; + this.nodeId = nodeId; + this.futVer = futVer; + this.addDepInfo = addDepInfo; + } + + /** {@inheritDoc} */ + @Override public int lookupIndex() { + return CACHE_MSG_IDX; + } + + /** + * @return Node ID this response should be sent to. + */ + public UUID nodeId() { + return nodeId; + } + + /** + * @param nodeId Node ID. + */ + public void nodeId(UUID nodeId) { + this.nodeId = nodeId; + } + + /** + * @return Future version. + */ + public GridCacheVersion futureVersion() { + return futVer; + } + + /** + * Sets update error. + * + * @param err Error. + */ + public void error(IgniteCheckedException err){ + this.err = err; + } + + /** {@inheritDoc} */ + @Override public IgniteCheckedException error() { + return err; + } + + /** + * @return Collection of failed keys. + */ + public Collection failedKeys() { + return failedKeys; + } + + /** + * @return Return value. + */ + public GridCacheReturn returnValue() { + return ret; + } + + /** + * @param ret Return value. + */ + @SuppressWarnings("unchecked") + public void returnValue(GridCacheReturn ret) { + this.ret = ret; + } + + /** + * @param remapKeys Remap keys. + */ + public void remapKeys(List remapKeys) { + this.remapKeys = remapKeys; + } + + /** + * @return Remap keys. + */ + public Collection remapKeys() { + return remapKeys; + } + + /** + * Adds value to be put in near cache on originating node. + * + * @param keyIdx Key index. + * @param val Value. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + public void addNearValue(int keyIdx, + @Nullable CacheObject val, + long ttl, + long expireTime) { + if (nearValsIdxs == null) { + nearValsIdxs = new ArrayList<>(); + nearVals = new ArrayList<>(); + } + + addNearTtl(keyIdx, ttl, expireTime); + + nearValsIdxs.add(keyIdx); + nearVals.add(val); + } + + /** + * @param keyIdx Key index. + * @param ttl TTL for near cache update. + * @param expireTime Expire time for near cache update. + */ + @SuppressWarnings("ForLoopReplaceableByForEach") + public void addNearTtl(int keyIdx, long ttl, long expireTime) { + if (ttl >= 0) { + if (nearTtls == null) { + nearTtls = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearTtls.add(-1L); + } + } + + if (nearTtls != null) + nearTtls.add(ttl); + + if (expireTime >= 0) { + if (nearExpireTimes == null) { + nearExpireTimes = new GridLongList(16); + + for (int i = 0; i < keyIdx; i++) + nearExpireTimes.add(-1); + } + } + + if (nearExpireTimes != null) + nearExpireTimes.add(expireTime); + } + + /** + * @param idx Index. + * @return Expire time for near cache update. + */ + public long nearExpireTime(int idx) { + if (nearExpireTimes != null) { + assert idx >= 0 && idx < nearExpireTimes.size(); + + return nearExpireTimes.get(idx); + } + + return -1L; + } + + /** + * @param idx Index. + * @return TTL for near cache update. + */ + public long nearTtl(int idx) { + if (nearTtls != null) { + assert idx >= 0 && idx < nearTtls.size(); + + return nearTtls.get(idx); + } + + return -1L; + } + + /** + * @param nearVer Version generated on primary node to be used for originating node's near cache update. + */ + public void nearVersion(GridCacheVersion nearVer) { + this.nearVer = nearVer; + } + + /** + * @return Version generated on primary node to be used for originating node's near cache update. + */ + public GridCacheVersion nearVersion() { + return nearVer; + } + + /** + * @param keyIdx Index of key for which update was skipped + */ + public void addSkippedIndex(int keyIdx) { + if (nearSkipIdxs == null) + nearSkipIdxs = new ArrayList<>(); + + nearSkipIdxs.add(keyIdx); + + addNearTtl(keyIdx, -1L, -1L); + } + + /** + * @return Indexes of keys for which update was skipped + */ + @Nullable public List skippedIndexes() { + return nearSkipIdxs; + } + + /** + * @return Indexes of keys for which values were generated on primary node. + */ + @Nullable public List nearValuesIndexes() { + return nearValsIdxs; + } + + /** + * @param idx Index. + * @return Value generated on primary node which should be put to originating node's near cache. + */ + @Nullable public CacheObject nearValue(int idx) { + return nearVals.get(idx); + } + + /** + * Adds key to collection of failed keys. + * + * @param key Key to add. + * @param e Error cause. + */ + public synchronized void addFailedKey(KeyCacheObject key, Throwable e) { + if (failedKeys == null) + failedKeys = new ConcurrentLinkedQueue<>(); + + failedKeys.add(key); + + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); + + err.addSuppressed(e); + } + + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + */ + public synchronized void addFailedKeys(Collection keys, Throwable e) { + if (keys != null) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); + + failedKeys.addAll(keys); + } -public interface GridNearAtomicUpdateResponse { + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); - int lookupIndex(); + err.addSuppressed(e); + } - UUID nodeId(); + /** + * Adds keys to collection of failed keys. + * + * @param keys Key to add. + * @param e Error cause. + * @param ctx Context. + */ + public synchronized void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx) { + if (failedKeys == null) + failedKeys = new ArrayList<>(keys.size()); - void nodeId(UUID nodeId); + failedKeys.addAll(keys); - GridCacheVersion futureVersion(); + if (err == null) + err = new IgniteCheckedException("Failed to update keys on primary node."); - void error(IgniteCheckedException err); + err.addSuppressed(e); + } - IgniteCheckedException error(); + /** {@inheritDoc} + * @param ctx*/ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); - Collection failedKeys(); + if (err != null && errBytes == null) + errBytes = ctx.marshaller().marshal(err); - GridCacheReturn returnValue(); + GridCacheContext cctx = ctx.cacheContext(cacheId); - @SuppressWarnings("unchecked") void returnValue(GridCacheReturn ret); + prepareMarshalCacheObjects(failedKeys, cctx); - void remapKeys(List remapKeys); + prepareMarshalCacheObjects(remapKeys, cctx); - Collection remapKeys(); + prepareMarshalCacheObjects(nearVals, cctx); - void addNearValue(int keyIdx, - @Nullable CacheObject val, - long ttl, - long expireTime); + if (ret != null) + ret.prepareMarshal(cctx); + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (errBytes != null && err == null) + err = ctx.marshaller().unmarshal(errBytes, ldr); + + GridCacheContext cctx = ctx.cacheContext(cacheId); + + finishUnmarshalCacheObjects(failedKeys, cctx, ldr); + + finishUnmarshalCacheObjects(remapKeys, cctx, ldr); + + finishUnmarshalCacheObjects(nearVals, cctx, ldr); + + if (ret != null) + ret.finishUnmarshal(cctx, ldr); + } + + /** {@inheritDoc} */ + @Override public boolean addDeploymentInfo() { + return addDepInfo; + } + + /** {@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.writeByteArray("errBytes", errBytes)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeCollection("failedKeys", failedKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeMessage("futVer", futVer)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeMessage("nearExpireTimes", nearExpireTimes)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeCollection("nearSkipIdxs", nearSkipIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeMessage("nearTtls", nearTtls)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeCollection("nearVals", nearVals, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeCollection("nearValsIdxs", nearValsIdxs, MessageCollectionItemType.INT)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeMessage("nearVer", nearVer)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeCollection("remapKeys", remapKeys, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeMessage("ret", ret)) + 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: + errBytes = reader.readByteArray("errBytes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + failedKeys = reader.readCollection("failedKeys", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + futVer = reader.readMessage("futVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + nearExpireTimes = reader.readMessage("nearExpireTimes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + nearSkipIdxs = reader.readCollection("nearSkipIdxs", MessageCollectionItemType.INT); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + nearTtls = reader.readMessage("nearTtls"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + nearVals = reader.readCollection("nearVals", MessageCollectionItemType.MSG); - @SuppressWarnings("ForLoopReplaceableByForEach") void addNearTtl(int keyIdx, long ttl, long expireTime); + if (!reader.isLastRead()) + return false; - long nearExpireTime(int idx); + reader.incrementState(); - long nearTtl(int idx); + case 10: + nearValsIdxs = reader.readCollection("nearValsIdxs", MessageCollectionItemType.INT); - void nearVersion(GridCacheVersion nearVer); + if (!reader.isLastRead()) + return false; - GridCacheVersion nearVersion(); + reader.incrementState(); - void addSkippedIndex(int keyIdx); + case 11: + nearVer = reader.readMessage("nearVer"); - @Nullable List skippedIndexes(); + if (!reader.isLastRead()) + return false; - @Nullable List nearValuesIndexes(); + reader.incrementState(); - @Nullable CacheObject nearValue(int idx); + case 12: + remapKeys = reader.readCollection("remapKeys", MessageCollectionItemType.MSG); - void addFailedKey(KeyCacheObject key, Throwable e); + if (!reader.isLastRead()) + return false; - void addFailedKeys(Collection keys, Throwable e); + reader.incrementState(); - void addFailedKeys(Collection keys, Throwable e, GridCacheContext ctx); + case 13: + ret = reader.readMessage("ret"); - void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException; + if (!reader.isLastRead()) + return false; - void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException; + reader.incrementState(); - boolean addDeploymentInfo(); + } - boolean writeTo(ByteBuffer buf, MessageWriter writer); + return reader.afterMessageRead(GridNearAtomicUpdateResponse.class); + } - boolean readFrom(ByteBuffer buf, MessageReader reader); + /** {@inheritDoc} */ + @Override public byte directType() { + return 41; + } - byte directType(); + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 14; + } - byte fieldsCount(); + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearAtomicUpdateResponse.class, this, "parent"); + } } 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 1a2eb22b0938e..c37fd5b9f9037 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 @@ -55,7 +55,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture; import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal; @@ -150,8 +150,8 @@ public GridDhtColocatedCache(GridCacheContext ctx, GridCacheConcurrentMap } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV1 res) { processLockResponse(nodeId, res); } }); @@ -1076,7 +1076,7 @@ else if (!b) * @param nodeId Node ID. * @param res Response. */ - private void processLockResponse(UUID nodeId, GridNearLockResponse res) { + private void processLockResponse(UUID nodeId, GridNearLockResponseV1 res) { assert nodeId != null; assert res != null; 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 e4c6b712989e2..515c590dd6616 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 @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; @@ -38,15 +39,21 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture; 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.dht.GridDhtCacheEntry; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockFuture; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockMapping; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV2; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV2; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; @@ -147,6 +154,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture /** Keep binary. */ private final boolean keepBinary; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Registry. * @param keys Keys to lock. @@ -425,7 +434,14 @@ void onResult(UUID nodeId, GridNearLockResponse res) { log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); - MiniFuture mini = miniFuture(res.miniId()); + int miniId; + + if (res instanceof GridNearLockResponseV1) + miniId = (int) ((GridNearLockResponseV1)res).miniId().localId(); + else + miniId = ((GridNearLockResponseV2)res).miniId(); + + MiniFuture mini = miniFuture(miniId); if (mini != null) { assert mini.node().id().equals(nodeId); @@ -457,7 +473,7 @@ else if (log.isDebugEnabled()) * @return Mini future. */ @SuppressWarnings({"ForLoopReplaceableByForEach", "IfMayBeConditional"}) - private MiniFuture miniFuture(IgniteUuid miniId) { + private MiniFuture miniFuture(int miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (futs) { // Avoid iterator creation. @@ -469,7 +485,7 @@ private MiniFuture miniFuture(IgniteUuid miniId) { MiniFuture mini = (MiniFuture)fut; - if (mini.futureId().equals(miniId)) { + if (mini.futureId() == miniId) { if (!mini.isDone()) return mini; else @@ -813,7 +829,7 @@ private synchronized void map0( assert !mappedKeys.isEmpty(); - GridNearLockRequest req = null; + GridNearLockRequestV1 req = null; Collection distributedKeys = new ArrayList<>(mappedKeys.size()); @@ -880,7 +896,7 @@ private synchronized void map0( first = false; } - req = new GridNearLockRequest( + req = new GridNearLockRequestV1( cctx.cacheId(), topVer, cctx.nodeId(), @@ -1030,7 +1046,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { assert fut != null; @@ -1045,7 +1061,7 @@ private void proceedMapping0() if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, ((GridCacheMessage)req), cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { assert fut != null; @@ -1306,7 +1322,7 @@ private class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private int futId = counter.incrementAndGet(); /** Node ID. */ @GridToStringExclude @@ -1334,7 +1350,7 @@ private class MiniFuture extends GridFutureAdapter { /** * @return Future ID. */ - IgniteUuid futureId() { + int futureId() { return futId; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 168076a4af169..63c073d56be1b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -43,7 +43,6 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; 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 5d4fc01eee3f8..ecc75110295ec 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 @@ -20,12 +20,18 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterNode; @@ -39,6 +45,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture; import org.apache.ignite.internal.processors.cache.KeyCacheObject; @@ -63,6 +70,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; +import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.transactions.TransactionIsolation; import org.jetbrains.annotations.Nullable; @@ -73,8 +81,11 @@ /** * Cache lock future. */ -public final class GridNearLockFuture extends GridCompoundIdentityFuture +public final class GridNearLockFuture extends GridFutureAdapter implements GridCacheMvccFuture { + + public static final UUID DUMMY_UUID = new UUID(0L, 0L); + /** */ private static final long serialVersionUID = 0L; @@ -154,6 +165,11 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture sent = new HashMap<>(); + + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Registry. * @param keys Keys to lock. @@ -177,7 +193,6 @@ public GridNearLockFuture( CacheEntryPredicate[] filter, boolean skipStore, boolean keepBinary) { - super(CU.boolReducer()); assert keys != null; @@ -423,22 +438,18 @@ public void complete(boolean success) { * @return {@code True} if node was in the list. */ @SuppressWarnings({"ThrowableInstanceNeverThrown"}) - @Override public boolean onNodeLeft(UUID nodeId) { + @Override public synchronized boolean onNodeLeft(UUID nodeId) { boolean found = false; - for (IgniteInternalFuture fut : futures()) { - if (isMini(fut)) { - MiniFuture f = (MiniFuture)fut; - - if (f.node().id().equals(nodeId)) { - if (log.isDebugEnabled()) - log.debug("Found mini-future for left node [nodeId=" + nodeId + ", mini=" + f + ", fut=" + - this + ']'); + for (GridNearLockMapping mapping : sent.values()) { + if (mapping.node().id().equals(nodeId)) { + if (log.isDebugEnabled()) + log.debug("Found mini-future for left node [nodeId=" + nodeId + ", mini=" + mapping + ", fut=" + + this + ']'); - f.onResult(newTopologyException(null, nodeId)); + onDone(newTopologyException(null, nodeId)); - found = true; - } + found = true; } } @@ -460,63 +471,252 @@ void onResult(UUID nodeId, GridNearLockResponse res) { if (log.isDebugEnabled()) log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); - MiniFuture mini = miniFuture(res.miniId()); + int miniId; - if (mini != null) { - assert mini.node().id().equals(nodeId); + if (res instanceof GridNearLockResponseV2) + miniId = ((GridNearLockResponseV2)res).miniId(); + else + miniId = (int)((GridNearLockResponseV1)res).miniId().localId(); - if (log.isDebugEnabled()) - log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']'); + GridNearLockMapping mapping; - mini.onResult(res); + synchronized (this) { + mapping = sent.remove(miniId); + } - if (log.isDebugEnabled()) - log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini + - ", res=" + res + ']'); + if (mapping == null) { + U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res + + ", fut=" + this + ']'); return; } - U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res + - ", fut=" + this + ']'); + assert mapping.node().id().equals(nodeId); + + if (log.isDebugEnabled()) + log.debug("Found mini future for response [mini=" + mapping + ", res=" + res + ']'); + + onResult(nodeId, res, mapping); + + checkComplete(); + + if (log.isDebugEnabled()) + log.debug("Future after processed lock response [fut=" + this + ", mini=" + mapping + + ", res=" + res + ']'); + } else if (log.isDebugEnabled()) log.debug("Ignoring lock response from node (future is done) [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); } - /** - * Finds pending mini future by the given mini ID. - * - * @param miniId Mini ID to find. - * @return Mini future. - */ - @SuppressWarnings({"ForLoopReplaceableByForEach", "IfMayBeConditional"}) - 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 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; + private void remap() { + undoLocks(false, false); + + mapOnTopology(true); + } + + private void onResult(UUID nodeId, GridNearLockResponse res, GridNearLockMapping mapping) { + if (res.error() != null) { + if (log.isDebugEnabled()) + log.debug("Finishing mini future with an error due to error in response [miniFut=" + this + + ", res=" + res + ']'); + + // Fail. + if (res.error() instanceof GridCacheLockTimeoutException) + onDone(false); + else + onDone(res.error()); + + return; + } + + if (res.clientRemapVersion() != null) { + assert cctx.kernalContext().clientNode(); + + IgniteInternalFuture affFut = + cctx.shared().exchange().affinityReadyFuture(res.clientRemapVersion()); + + if (affFut != null && !affFut.isDone()) { + affFut.listen(new CI1>() { + @Override public void apply(IgniteInternalFuture fut) { + try { + fut.get(); + + remap(); + } + catch (IgniteCheckedException e) { + onDone(e); + } + finally { + cctx.shared().txContextReset(); + } + } + }); + } + else + remap(); + + return; + } + + int i = 0; + + for (KeyCacheObject k : mapping.mappedKeys()) { + while (true) { + + GridNearCacheEntry entry = cctx.near().entryExx(k, topVer); + + if (res.dhtVersion(i) == null) { + onDone(new IgniteCheckedException("Failed to receive DHT version from remote node " + + "(will fail the lock): " + res)); + + return; } + + IgniteBiTuple oldValTup = + valMap.get(entry.key()); + + boolean hasBytes = entry.hasValue(); + CacheObject oldVal = entry.rawGet(); + CacheObject newVal = res.value(i); + + GridCacheVersion dhtVer = res.dhtVersion(i); + GridCacheVersion mappedVer = res.mappedVersion(i); + + if (newVal == null) { + if (oldValTup != null) { + if (oldValTup.get1().equals(dhtVer)) + newVal = oldValTup.get2(); + + oldVal = oldValTup.get2(); + } + } + + try { + + // Lock is held at this point, so we can set the + // returned value if any. + entry.resetFromPrimary(newVal, lockVer, dhtVer, nodeId, topVer); + + entry.readyNearLock(lockVer, + mappedVer, + res.committedVersions(), + res.rolledbackVersions(), + res.pending()); + + if (mapping.node().isLocal()) { + // On local node don't record twice if DHT cache already recorded. + boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); + + if (inTx() && implicitTx() && tx.onePhaseCommit()) { + boolean pass = res.filterResult(i); + + tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); + } + + if (record) { + if (cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) + cctx.events().addEvent( + entry.partition(), + entry.key(), + tx, + null, + EVT_CACHE_OBJECT_READ, + newVal, + newVal != null, + oldVal, + hasBytes, + CU.subjectId(tx, cctx.shared()), + null, + inTx() ? tx.resolveTaskName() : null, + keepBinary); + + if (cctx.cache().configuration().isStatisticsEnabled()) + cctx.cache().metrics0().onRead(oldVal != null); + } + + if (log.isDebugEnabled()) + log.debug("Processed response for entry [res=" + res + + ", entry=" + entry + ']'); + + break; // Inner while loop. + } + else { + + boolean readRecordable = false; + + boolean hasOldVal = false; + if (retval) { + readRecordable = cctx.events().isRecordable(EVT_CACHE_OBJECT_READ); + + if (readRecordable) + hasOldVal = entry.hasValue(); + } + + if (inTx()) { + tx.hasRemoteLocks(true); + + if (implicitTx() && tx.onePhaseCommit()) { + boolean pass = res.filterResult(i); + + tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); + } + } + + if (retval) { + if (readRecordable) + cctx.events().addEvent( + entry.partition(), + entry.key(), + tx, + null, + EVT_CACHE_OBJECT_READ, + newVal, + newVal != null, + oldVal, + hasOldVal, + CU.subjectId(tx, cctx.shared()), + null, + inTx() ? tx.resolveTaskName() : null, + keepBinary); + + if (cctx.cache().configuration().isStatisticsEnabled()) + cctx.cache().metrics0().onRead(false); + } + + if (log.isDebugEnabled()) + log.debug("Processed response for entry [res=" + res + ", entry=" + entry + ']'); + + break; // Inner while loop. + } + + } + catch (GridCacheEntryRemovedException ignored) { + if (log.isDebugEnabled()) + log.debug("Failed to add candidates because entry was " + + "removed (will renew)."); + + synchronized (this) { + // Replace old entry with new one. + entries.set(i, + (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); + } + } + } + i++; } - return null; + // Proceed and add new future (if any) before completing embedded future. + try { + proceedMapping(); + } + catch (IgniteCheckedException ex) { + onDone(false, ex); + } } - /** * @param t Error. */ @@ -545,7 +745,7 @@ private boolean filter(GridCacheEntryEx cached) { return true; } catch (IgniteCheckedException e) { - onError(e); + onDone(e); return false; } @@ -570,7 +770,7 @@ private boolean filter(GridCacheEntryEx cached) { * @return {@code True} if locks have been acquired. */ private boolean checkLocks() { - if (!isDone() && initialized() && !hasPending()) { + if (!isDone() && !hasPending()) { synchronized (this) { for (int i = 0; i < entries.size(); i++) { while (true) { @@ -613,6 +813,10 @@ private boolean checkLocks() { return false; } + private synchronized boolean hasPending() { + return !sent.isEmpty(); + } + /** {@inheritDoc} */ @Override public boolean cancel() { if (onCancelled()) @@ -680,32 +884,11 @@ private boolean onComplete(boolean success, boolean distribute) { /** {@inheritDoc} */ @Override public String toString() { - Collection futs = F.viewReadOnly(futures(), new C1, String>() { - @Override public String apply(IgniteInternalFuture f) { - if (isMini(f)) { - MiniFuture m = (MiniFuture)f; - - return "[node=" + m.node().id() + ", loc=" + m.node().isLocal() + ", done=" + f.isDone() + "]"; - } - else - return "[loc=true, done=" + f.isDone() + "]"; - } - }); - return S.toString(GridNearLockFuture.class, this, - "innerFuts", futs, "inTx", inTx(), "super", super.toString()); } - /** - * @param f Future. - * @return {@code True} if mini-future. - */ - private boolean isMini(IgniteInternalFuture f) { - return f.getClass().equals(MiniFuture.class); - } - /** * Basically, future mapping consists from two parts. First, we must determine the topology version this future * will map on. Locking is performed within a user transaction, we must continue to map keys on the same @@ -732,8 +915,8 @@ void map() { topVer = tx.topologyVersionSnapshot(); if (topVer != null) { - for (GridDhtTopologyFuture fut : cctx.shared().exchange().exchangeFutures()){ - if (fut.topologyVersion().equals(topVer)){ + for (GridDhtTopologyFuture fut : cctx.shared().exchange().exchangeFutures()) { + if (fut.topologyVersion().equals(topVer)) { Throwable err = fut.validateCache(cctx); if (err != null) { @@ -752,8 +935,6 @@ void map() { map(keys, false, true); - markInitialized(); - return; } @@ -807,8 +988,6 @@ synchronized void mapOnTopology(final boolean remap) { } map(keys, remap, false); - - markInitialized(); } else { fut.listen(new CI1>() { @@ -833,6 +1012,17 @@ synchronized void mapOnTopology(final boolean remap) { } } + private synchronized void checkComplete() { + if (isDone()) + return; + + if (err != null) + onDone(err); + + if (!hasPending()) + onDone(true); + } + /** * Maps keys to nodes. Note that we can not simply group keys by nodes and send lock request as * such approach does not preserve order of lock acquisition. Instead, keys are split in continuous @@ -996,31 +1186,70 @@ private void map(Iterable keys, boolean remap, boolean topLocked first = false; } - req = new GridNearLockRequest( - cctx.cacheId(), - topVer, - cctx.nodeId(), - threadId, - futId, - lockVer, - inTx(), - implicitTx(), - implicitSingleTx(), - read, - retval, - isolation(), - isInvalidate(), - timeout, - mappedKeys.size(), - inTx() ? tx.size() : mappedKeys.size(), - inTx() && tx.syncCommit(), - inTx() ? tx.subjectId() : null, - inTx() ? tx.taskNameHash() : 0, - read ? accessTtl : -1L, - skipStore, - keepBinary, - clientFirst, - cctx.deploymentEnabled()); + boolean optimize = true; + + Collection topNodes = CU.affinityNodes(cctx, topVer); + + for (ClusterNode topNode : topNodes) { + if (topNode.version().compareTo(cctx.localNode().version()) < 0) { + optimize = false; + + break; + } + } + + if (optimize) + req = new GridNearLockRequestV2( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); + else + req = new GridNearLockRequestV1( + cctx.cacheId(), + topVer, + cctx.nodeId(), + threadId, + futId, + lockVer, + inTx(), + implicitTx(), + implicitSingleTx(), + read, + retval, + isolation(), + isInvalidate(), + timeout, + mappedKeys.size(), + inTx() ? tx.size() : mappedKeys.size(), + inTx() && tx.syncCommit(), + inTx() ? tx.subjectId() : null, + inTx() ? tx.taskNameHash() : 0, + read ? accessTtl : -1L, + skipStore, + keepBinary, + clientFirst, + cctx.deploymentEnabled()); mapping.request(req); } @@ -1083,9 +1312,11 @@ private void map(Iterable keys, boolean remap, boolean topLocked cctx.mvcc().recheckPendingLocks(); proceedMapping(); + + checkComplete(); } catch (IgniteCheckedException ex) { - onError(ex); + onDone(ex); } } @@ -1124,157 +1355,42 @@ private void proceedMapping0() return; final GridNearLockRequest req = map.request(); - final Collection mappedKeys = map.distributedKeys(); final ClusterNode node = map.node(); if (filter != null && filter.length != 0) req.filter(filter, cctx); - if (node.isLocal()) { - req.miniId(IgniteUuid.randomUuid()); - - if (log.isDebugEnabled()) - log.debug("Before locally locking near request: " + req); - - IgniteInternalFuture fut = dht().lockAllAsync(cctx, cctx.localNode(), req, filter); - - // Add new future. - add(new GridEmbeddedFuture<>( - new C2() { - @Override public Boolean apply(GridNearLockResponse res, Exception e) { - if (CU.isLockTimeoutOrCancelled(e) || - (res != null && CU.isLockTimeoutOrCancelled(res.error()))) - return false; - - if (e != null) { - onError(e); - - return false; - } - - if (res == null) { - onError(new IgniteCheckedException("Lock response is null for future: " + this)); + int miniId = counter.incrementAndGet(); - return false; - } + synchronized (this) { + sent.put(miniId, map); + } - if (res.error() != null) { - onError(res.error()); + req.miniId(miniId); - return false; - } + if (node.isLocal()) { + if (log.isDebugEnabled()) { + log.debug("Before locally locking near request: " + req); + } - if (log.isDebugEnabled()) - log.debug("Acquired lock for local DHT mapping [locId=" + cctx.nodeId() + - ", mappedKeys=" + mappedKeys + ", fut=" + GridNearLockFuture.this + ']'); + final IgniteInternalFuture fut = dht().lockAllAsync(cctx, cctx.localNode(), req, filter); + fut.listen(new IgniteInClosure>() { + @Override public void apply(IgniteInternalFuture future) { + if (future.error() != null) + onDone(future.error()); + else { try { - int i = 0; - - for (KeyCacheObject k : mappedKeys) { - while (true) { - GridNearCacheEntry entry = cctx.near().entryExx(k, req.topologyVersion()); - - try { - IgniteBiTuple oldValTup = - valMap.get(entry.key()); - - boolean hasBytes = entry.hasValue(); - CacheObject oldVal = entry.rawGet(); - CacheObject newVal = res.value(i); - - GridCacheVersion dhtVer = res.dhtVersion(i); - GridCacheVersion mappedVer = res.mappedVersion(i); - - // On local node don't record twice if DHT cache already recorded. - boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); - - if (newVal == null) { - if (oldValTup != null) { - if (oldValTup.get1().equals(dhtVer)) - newVal = oldValTup.get2(); - - oldVal = oldValTup.get2(); - } - } - - // Lock is held at this point, so we can set the - // returned value if any. - entry.resetFromPrimary(newVal, lockVer, dhtVer, node.id(), topVer); - - entry.readyNearLock(lockVer, mappedVer, res.committedVersions(), - res.rolledbackVersions(), res.pending()); - - if (inTx() && implicitTx() && tx.onePhaseCommit()) { - boolean pass = res.filterResult(i); - - tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); - } - - if (record) { - if (cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) - cctx.events().addEvent( - entry.partition(), - entry.key(), - tx, - null, - EVT_CACHE_OBJECT_READ, - newVal, - newVal != null, - oldVal, - hasBytes, - CU.subjectId(tx, cctx.shared()), - null, - inTx() ? tx.resolveTaskName() : null, - keepBinary); - - if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(oldVal != null); - } - - if (log.isDebugEnabled()) - log.debug("Processed response for entry [res=" + res + - ", entry=" + entry + ']'); - - break; // Inner while loop. - } - catch (GridCacheEntryRemovedException ignored) { - if (log.isDebugEnabled()) - log.debug("Failed to add candidates because entry was " + - "removed (will renew)."); - - synchronized (GridNearLockFuture.this) { - // Replace old entry with new one. - entries.set(i, - (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); - } - } - } - - i++; // Increment outside of while loop. - } - - // Proceed and add new future (if any) before completing embedded future. - proceedMapping(); + onResult(node.id(), future.get()); } - catch (IgniteCheckedException ex) { - onError(ex); - - return false; + catch (IgniteCheckedException e) { + onDone(e); } - - return true; } - }, - fut)); + } + }); } else { - final MiniFuture fut = new MiniFuture(node, mappedKeys); - - req.miniId(fut.futureId()); - - add(fut); // Append new future. - IgniteInternalFuture txSync = null; if (inTx()) @@ -1285,10 +1401,10 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, (GridCacheMessage)req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { - fut.onResult(ex); + onDone(ex); } } else { @@ -1298,13 +1414,14 @@ boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer); if (log.isDebugEnabled()) log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']'); - cctx.io().send(node, req, cctx.ioPolicy()); + cctx.io().send(node, (GridCacheMessage)req, cctx.ioPolicy()); } catch (ClusterTopologyCheckedException ex) { - fut.onResult(ex); + tx.removeMapping(node.id()); + onError(newTopologyException(ex, node.id())); } catch (IgniteCheckedException e) { - onError(e); + onDone(e); } } }); @@ -1394,269 +1511,4 @@ private class LockTimeoutObject extends GridTimeoutObjectAdapter { return S.toString(LockTimeoutObject.class, this); } } - - /** - * Mini-future for get operations. Mini-futures are only waiting on a single - * node as opposed to multiple nodes. - */ - private class MiniFuture extends GridFutureAdapter { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); - - /** Node ID. */ - @GridToStringExclude - private ClusterNode node; - - /** Keys. */ - @GridToStringInclude - private Collection keys; - - /** */ - private boolean rcvRes; - - /** - * @param node Node. - * @param keys Keys. - */ - MiniFuture( - ClusterNode node, - Collection keys - ) { - this.node = node; - this.keys = keys; - } - - /** - * @return Future ID. - */ - IgniteUuid futureId() { - return futId; - } - - /** - * @return Node ID. - */ - public ClusterNode node() { - return node; - } - - /** - * @return Keys. - */ - public Collection keys() { - return keys; - } - - /** - * @param e Node left exception. - */ - void onResult(ClusterTopologyCheckedException e) { - if (isDone()) - return; - - synchronized (this) { - if (!rcvRes) - rcvRes = true; - else - return; - } - - if (log.isDebugEnabled()) - log.debug("Remote node left grid while sending or waiting for reply (will fail): " + this); - - if (tx != null) - tx.removeMapping(node.id()); - - // Primary node left the grid, so fail the future. - GridNearLockFuture.this.onDone(newTopologyException(e, node.id())); - - onDone(true); - } - - /** - * @param res Result callback. - */ - void onResult(GridNearLockResponse res) { - synchronized (this) { - if (!rcvRes) - rcvRes = true; - else - return; - } - - if (res.error() != null) { - if (log.isDebugEnabled()) - log.debug("Finishing mini future with an error due to error in response [miniFut=" + this + - ", res=" + res + ']'); - - // Fail. - if (res.error() instanceof GridCacheLockTimeoutException) - onDone(false); - else - onDone(res.error()); - - return; - } - - if (res.clientRemapVersion() != null) { - assert cctx.kernalContext().clientNode(); - - IgniteInternalFuture affFut = - cctx.shared().exchange().affinityReadyFuture(res.clientRemapVersion()); - - if (affFut != null && !affFut.isDone()) { - affFut.listen(new CI1>() { - @Override public void apply(IgniteInternalFuture fut) { - try { - fut.get(); - - remap(); - } - catch (IgniteCheckedException e) { - onDone(e); - } - finally { - cctx.shared().txContextReset(); - } - } - }); - } - else - remap(); - } - else { - int i = 0; - - AffinityTopologyVersion topVer = GridNearLockFuture.this.topVer; - - for (KeyCacheObject k : keys) { - while (true) { - GridNearCacheEntry entry = cctx.near().entryExx(k, topVer); - - try { - if (res.dhtVersion(i) == null) { - onDone(new IgniteCheckedException("Failed to receive DHT version from remote node " + - "(will fail the lock): " + res)); - - return; - } - - IgniteBiTuple oldValTup = valMap.get(entry.key()); - - CacheObject oldVal = entry.rawGet(); - boolean hasOldVal = false; - CacheObject newVal = res.value(i); - - boolean readRecordable = false; - - if (retval) { - readRecordable = cctx.events().isRecordable(EVT_CACHE_OBJECT_READ); - - if (readRecordable) - hasOldVal = entry.hasValue(); - } - - GridCacheVersion dhtVer = res.dhtVersion(i); - GridCacheVersion mappedVer = res.mappedVersion(i); - - if (newVal == null) { - if (oldValTup != null) { - if (oldValTup.get1().equals(dhtVer)) - newVal = oldValTup.get2(); - - oldVal = oldValTup.get2(); - } - } - - // Lock is held at this point, so we can set the - // returned value if any. - entry.resetFromPrimary(newVal, lockVer, dhtVer, node.id(), topVer); - - if (inTx()) { - tx.hasRemoteLocks(true); - - if (implicitTx() && tx.onePhaseCommit()) { - boolean pass = res.filterResult(i); - - tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr()); - } - } - - entry.readyNearLock(lockVer, - mappedVer, - res.committedVersions(), - res.rolledbackVersions(), - res.pending()); - - if (retval) { - if (readRecordable) - cctx.events().addEvent( - entry.partition(), - entry.key(), - tx, - null, - EVT_CACHE_OBJECT_READ, - newVal, - newVal != null, - oldVal, - hasOldVal, - CU.subjectId(tx, cctx.shared()), - null, - inTx() ? tx.resolveTaskName() : null, - keepBinary); - - if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(false); - } - - if (log.isDebugEnabled()) - log.debug("Processed response for entry [res=" + res + ", entry=" + entry + ']'); - - break; // Inner while loop. - } - catch (GridCacheEntryRemovedException ignored) { - if (log.isDebugEnabled()) - log.debug("Failed to add candidates because entry was removed (will renew)."); - - synchronized (GridNearLockFuture.this) { - // Replace old entry with new one. - entries.set(i, - (GridDistributedCacheEntry)cctx.cache().entryEx(entry.key())); - } - } - } - - i++; - } - - try { - proceedMapping(); - } - catch (IgniteCheckedException e) { - onDone(e); - } - - onDone(true); - } - } - - /** - * - */ - private void remap() { - undoLocks(false, false); - - mapOnTopology(true); - - onDone(true); - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(MiniFuture.class, this, "node", node.id(), "super", super.toString()); - } - } } 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 2a6b0a8b373e7..59ab746e4cd3b 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 @@ -1,596 +1,88 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.apache.ignite.internal.processors.cache.distributed.near; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Arrays; -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.GridCacheDeployable; 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; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.transactions.TransactionIsolation; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -/** - * Near cache lock request. - */ -public class GridNearLockRequest extends GridDistributedLockRequest { - /** */ - private static final long serialVersionUID = 0L; - - /** Topology version. */ - private AffinityTopologyVersion topVer; - - /** Mini future ID. */ - private IgniteUuid miniId; - - /** Filter. */ - private CacheEntryPredicate[] filter; - - /** Implicit flag. */ - private boolean implicitTx; - - /** Implicit transaction with one key flag. */ - private boolean implicitSingleTx; - - /** Flag is kept for backward compatibility. */ - private boolean onePhaseCommit; - - /** Array of mapped DHT versions for this entry. */ - @GridToStringInclude - private GridCacheVersion[] dhtVers; - - /** Subject ID. */ - private UUID subjId; - - /** Task name hash. */ - private int taskNameHash; - - /** Has transforms flag. */ - private boolean hasTransforms; - - /** Sync commit flag. */ - private boolean syncCommit; - - /** TTL for read operation. */ - private long accessTtl; - - /** Flag indicating whether cache operation requires a previous value. */ - private boolean retVal; - - /** {@code True} if first lock request for lock operation sent from client node. */ - private boolean firstClientReq; - - /** - * Empty constructor required for {@link Externalizable}. - */ - public GridNearLockRequest() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param topVer Topology version. - * @param nodeId Node ID. - * @param threadId Thread ID. - * @param futId Future ID. - * @param lockVer Cache version. - * @param isInTx {@code True} if implicit transaction lock. - * @param implicitTx Flag to indicate that transaction is implicit. - * @param implicitSingleTx Implicit-transaction-with-one-key flag. - * @param isRead Indicates whether implicit lock is for read or write operation. - * @param retVal Return value flag. - * @param isolation Transaction isolation. - * @param isInvalidate Invalidation flag. - * @param timeout Lock timeout. - * @param keyCnt Number of keys. - * @param txSize Expected transaction size. - * @param syncCommit Synchronous commit flag. - * @param subjId Subject ID. - * @param taskNameHash Task name hash code. - * @param accessTtl TTL for read operation. - * @param skipStore Skip store flag. - * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. - * @param addDepInfo Deployment info flag. - */ - public GridNearLockRequest( - int cacheId, - @NotNull AffinityTopologyVersion topVer, - UUID nodeId, - long threadId, - IgniteUuid futId, - GridCacheVersion lockVer, - boolean isInTx, - boolean implicitTx, - boolean implicitSingleTx, - boolean isRead, - boolean retVal, - TransactionIsolation isolation, - boolean isInvalidate, - long timeout, - int keyCnt, - int txSize, - boolean syncCommit, - @Nullable UUID subjId, - int taskNameHash, - long accessTtl, - boolean skipStore, - boolean keepBinary, - boolean firstClientReq, - boolean addDepInfo - - ) { - super( - cacheId, - nodeId, - lockVer, - threadId, - futId, - lockVer, - isInTx, - isRead, - isolation, - isInvalidate, - timeout, - keyCnt, - txSize, - skipStore, - keepBinary, - addDepInfo); - - assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; - - this.topVer = topVer; - this.implicitTx = implicitTx; - this.implicitSingleTx = implicitSingleTx; - this.syncCommit = syncCommit; - this.subjId = subjId; - this.taskNameHash = taskNameHash; - this.accessTtl = accessTtl; - this.retVal = retVal; - this.firstClientReq = firstClientReq; - - dhtVers = new GridCacheVersion[keyCnt]; - } - - /** - * @return {@code True} if first lock request for lock operation sent from client node. - */ - public boolean firstClientRequest() { - return firstClientReq; - } - - /** - * @return Topology version. - */ - @Override public AffinityTopologyVersion topologyVersion() { - return topVer; - } - - /** - * @return Subject ID. - */ - public UUID subjectId() { - return subjId; - } - - /** - * @return Task name hash.q - */ - public int taskNameHash() { - return taskNameHash; - } - - /** - * @return Implicit transaction flag. - */ - public boolean implicitTx() { - return implicitTx; - } - - /** - * @return Implicit-transaction-with-one-key flag. - */ - public boolean implicitSingleTx() { - return implicitSingleTx; - } - - /** - * @return Sync commit flag. - */ - public boolean syncCommit() { - return syncCommit; - } - - /** - * @return Filter. - */ - public CacheEntryPredicate[] filter() { - return filter; - } - - /** - * @param filter Filter. - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) - throws IgniteCheckedException { - this.filter = filter; - } - - /** - * @return Mini future ID. - */ - public IgniteUuid miniId() { - return miniId; - } - - /** - * @param miniId Mini future Id. - */ - public void miniId(IgniteUuid miniId) { - this.miniId = miniId; - } - - /** - * @param hasTransforms {@code True} if originating transaction has transform entries. - */ - public void hasTransforms(boolean hasTransforms) { - this.hasTransforms = hasTransforms; - } - - /** - * @return {@code True} if originating transaction has transform entries. - */ - public boolean hasTransforms() { - return hasTransforms; - } - - /** - * @return Need return value flag. - */ - public boolean needReturnValue() { - return retVal; - } - - /** - * Adds a key. - * - * @param key Key. - * @param retVal Flag indicating whether value should be returned. - * @param dhtVer DHT version. - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void addKeyBytes( - KeyCacheObject key, - boolean retVal, - @Nullable GridCacheVersion dhtVer, - GridCacheContext ctx - ) throws IgniteCheckedException { - dhtVers[idx] = dhtVer; - - // Delegate to super. - addKeyBytes(key, retVal, ctx); - } - - /** - * @param idx Index of the key. - * @return DHT version for key at given index. - */ - public GridCacheVersion dhtVersion(int idx) { - return dhtVers[idx]; - } - - /** - * @return TTL for read operation. - */ - public long accessTtl() { - return accessTtl; - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (filter != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId); - - for (CacheEntryPredicate p : filter) { - if (p != null) - p.prepareMarshal(cctx); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (filter != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId); - - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - } - - /** {@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 20: - if (!writer.writeLong("accessTtl", accessTtl)) - return false; - - writer.incrementState(); - - case 21: - if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 22: - if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 23: - if (!writer.writeBoolean("firstClientReq", firstClientReq)) - return false; - - writer.incrementState(); - - case 24: - if (!writer.writeBoolean("hasTransforms", hasTransforms)) - return false; - - writer.incrementState(); - - case 25: - if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) - return false; - - writer.incrementState(); - - case 26: - if (!writer.writeBoolean("implicitTx", implicitTx)) - return false; - - writer.incrementState(); - - case 27: - if (!writer.writeIgniteUuid("miniId", miniId)) - return false; - - writer.incrementState(); - - case 28: - if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) - return false; - - writer.incrementState(); - - case 29: - if (!writer.writeBoolean("retVal", retVal)) - return false; - - writer.incrementState(); - - case 30: - if (!writer.writeUuid("subjId", subjId)) - return false; - - writer.incrementState(); - - case 31: - if (!writer.writeBoolean("syncCommit", syncCommit)) - return false; - - writer.incrementState(); - - case 32: - if (!writer.writeInt("taskNameHash", taskNameHash)) - return false; - - writer.incrementState(); - - case 33: - if (!writer.writeMessage("topVer", topVer)) - 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 20: - accessTtl = reader.readLong("accessTtl"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 21: - dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 22: - filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 23: - firstClientReq = reader.readBoolean("firstClientReq"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 24: - hasTransforms = reader.readBoolean("hasTransforms"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 25: - implicitSingleTx = reader.readBoolean("implicitSingleTx"); +import java.util.List; +import java.util.UUID; - if (!reader.isLastRead()) - return false; +public interface GridNearLockRequest extends Message, GridCacheDeployable, GridCacheVersionable { + boolean firstClientRequest(); - reader.incrementState(); + AffinityTopologyVersion topologyVersion(); - case 26: - implicitTx = reader.readBoolean("implicitTx"); + UUID subjectId(); - if (!reader.isLastRead()) - return false; + int taskNameHash(); - reader.incrementState(); + boolean implicitTx(); - case 27: - miniId = reader.readIgniteUuid("miniId"); + boolean implicitSingleTx(); - if (!reader.isLastRead()) - return false; + boolean syncCommit(); - reader.incrementState(); + CacheEntryPredicate[] filter(); - case 28: - onePhaseCommit = reader.readBoolean("onePhaseCommit"); + void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException; - if (!reader.isLastRead()) - return false; + void hasTransforms(boolean hasTransforms); - reader.incrementState(); + boolean hasTransforms(); - case 29: - retVal = reader.readBoolean("retVal"); + boolean needReturnValue(); - if (!reader.isLastRead()) - return false; + void addKeyBytes( + KeyCacheObject key, + boolean retVal, + @Nullable GridCacheVersion dhtVer, + GridCacheContext ctx + ) throws IgniteCheckedException; - reader.incrementState(); + GridCacheVersion dhtVersion(int idx); - case 30: - subjId = reader.readUuid("subjId"); + long accessTtl(); - if (!reader.isLastRead()) - return false; + boolean txRead(); - reader.incrementState(); + long timeout(); - case 31: - syncCommit = reader.readBoolean("syncCommit"); + long threadId(); - if (!reader.isLastRead()) - return false; + boolean skipStore(); - reader.incrementState(); + boolean keepBinary(); - case 32: - taskNameHash = reader.readInt("taskNameHash"); + boolean inTx(); - if (!reader.isLastRead()) - return false; + List keys(); - reader.incrementState(); + IgniteUuid futureId(); - case 33: - topVer = reader.readMessage("topVer"); + TransactionIsolation isolation(); - if (!reader.isLastRead()) - return false; + boolean isInvalidate(); - reader.incrementState(); + int txSize(); - } + long messageId(); - return reader.afterMessageRead(GridNearLockRequest.class); - } + boolean returnValue(int idx); - /** {@inheritDoc} */ - @Override public byte directType() { - return 51; - } + int miniId(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 34; - } + void miniId(int miniId); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearLockRequest.class, this, "filter", Arrays.toString(filter), - "super", super.toString()); - } + IgniteUuid oldVersionMiniId(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java new file mode 100644 index 0000000000000..e305450cacf90 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV1.java @@ -0,0 +1,600 @@ +/* + * 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.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Arrays; +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.GridCacheSharedContext; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.transactions.TransactionIsolation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Near cache lock request. + */ +public class GridNearLockRequestV1 extends GridDistributedLockRequest implements GridNearLockRequest { + /** */ + private static final long serialVersionUID = 0L; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Mini future ID. */ + private IgniteUuid miniId; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + /** Implicit flag. */ + private boolean implicitTx; + + /** Implicit transaction with one key flag. */ + private boolean implicitSingleTx; + + /** Flag is kept for backward compatibility. */ + private boolean onePhaseCommit; + + /** Array of mapped DHT versions for this entry. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** Has transforms flag. */ + private boolean hasTransforms; + + /** Sync commit flag. */ + private boolean syncCommit; + + /** TTL for read operation. */ + private long accessTtl; + + /** Flag indicating whether cache operation requires a previous value. */ + private boolean retVal; + + /** {@code True} if first lock request for lock operation sent from client node. */ + private boolean firstClientReq; + + /** + * Empty constructor required for {@link Externalizable}. + */ + public GridNearLockRequestV1() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param topVer Topology version. + * @param nodeId Node ID. + * @param threadId Thread ID. + * @param futId Future ID. + * @param lockVer Cache version. + * @param isInTx {@code True} if implicit transaction lock. + * @param implicitTx Flag to indicate that transaction is implicit. + * @param implicitSingleTx Implicit-transaction-with-one-key flag. + * @param isRead Indicates whether implicit lock is for read or write operation. + * @param retVal Return value flag. + * @param isolation Transaction isolation. + * @param isInvalidate Invalidation flag. + * @param timeout Lock timeout. + * @param keyCnt Number of keys. + * @param txSize Expected transaction size. + * @param syncCommit Synchronous commit flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param accessTtl TTL for read operation. + * @param skipStore Skip store flag. + * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. + * @param addDepInfo Deployment info flag. + */ + public GridNearLockRequestV1( + int cacheId, + @NotNull AffinityTopologyVersion topVer, + UUID nodeId, + long threadId, + IgniteUuid futId, + GridCacheVersion lockVer, + boolean isInTx, + boolean implicitTx, + boolean implicitSingleTx, + boolean isRead, + boolean retVal, + TransactionIsolation isolation, + boolean isInvalidate, + long timeout, + int keyCnt, + int txSize, + boolean syncCommit, + @Nullable UUID subjId, + int taskNameHash, + long accessTtl, + boolean skipStore, + boolean keepBinary, + boolean firstClientReq, + boolean addDepInfo + + ) { + super( + cacheId, + nodeId, + lockVer, + threadId, + futId, + lockVer, + isInTx, + isRead, + isolation, + isInvalidate, + timeout, + keyCnt, + txSize, + skipStore, + keepBinary, + addDepInfo); + + assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; + + this.topVer = topVer; + this.implicitTx = implicitTx; + this.implicitSingleTx = implicitSingleTx; + this.syncCommit = syncCommit; + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.accessTtl = accessTtl; + this.retVal = retVal; + this.firstClientReq = firstClientReq; + + dhtVers = new GridCacheVersion[keyCnt]; + } + + /** + * @return {@code True} if first lock request for lock operation sent from client node. + */ + @Override public boolean firstClientRequest() { + return firstClientReq; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Subject ID. + */ + @Override public UUID subjectId() { + return subjId; + } + + /** + * @return Task name hash.q + */ + @Override public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Implicit transaction flag. + */ + @Override public boolean implicitTx() { + return implicitTx; + } + + /** + * @return Implicit-transaction-with-one-key flag. + */ + @Override public boolean implicitSingleTx() { + return implicitSingleTx; + } + + /** + * @return Sync commit flag. + */ + @Override public boolean syncCommit() { + return syncCommit; + } + + /** + * @return Filter. + */ + @Override public CacheEntryPredicate[] filter() { + return filter; + } + + /** + * @param filter Filter. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + @Override public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException { + this.filter = filter; + } + + /** + * @return Mini future ID. + */ + public int miniId() { + return (int) miniId.localId(); + } + + /** + * @param miniId Mini future Id. + */ + public void miniId(int miniId) { + this.miniId = new IgniteUuid(GridNearLockFuture.DUMMY_UUID, miniId); + } + + public IgniteUuid oldVersionMiniId() { + return miniId; + } + + /** + * @param hasTransforms {@code True} if originating transaction has transform entries. + */ + @Override public void hasTransforms(boolean hasTransforms) { + this.hasTransforms = hasTransforms; + } + + /** + * @return {@code True} if originating transaction has transform entries. + */ + @Override public boolean hasTransforms() { + return hasTransforms; + } + + /** + * @return Need return value flag. + */ + @Override public boolean needReturnValue() { + return retVal; + } + + /** + * Adds a key. + * + * @param key Key. + * @param retVal Flag indicating whether value should be returned. + * @param dhtVer DHT version. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + @Override public void addKeyBytes( + KeyCacheObject key, + boolean retVal, + @Nullable GridCacheVersion dhtVer, + GridCacheContext ctx + ) throws IgniteCheckedException { + dhtVers[idx] = dhtVer; + + // Delegate to super. + addKeyBytes(key, retVal, ctx); + } + + /** + * @param idx Index of the key. + * @return DHT version for key at given index. + */ + @Override public GridCacheVersion dhtVersion(int idx) { + return dhtVers[idx]; + } + + /** + * @return TTL for read operation. + */ + @Override public long accessTtl() { + return accessTtl; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.prepareMarshal(cctx); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + } + + /** {@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 20: + if (!writer.writeLong("accessTtl", accessTtl)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeBoolean("firstClientReq", firstClientReq)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeBoolean("hasTransforms", hasTransforms)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeBoolean("implicitSingleTx", implicitSingleTx)) + return false; + + writer.incrementState(); + + case 26: + if (!writer.writeBoolean("implicitTx", implicitTx)) + return false; + + writer.incrementState(); + + case 27: + if (!writer.writeIgniteUuid("miniId", miniId)) + return false; + + writer.incrementState(); + + case 28: + if (!writer.writeBoolean("onePhaseCommit", onePhaseCommit)) + return false; + + writer.incrementState(); + + case 29: + if (!writer.writeBoolean("retVal", retVal)) + return false; + + writer.incrementState(); + + case 30: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 31: + if (!writer.writeBoolean("syncCommit", syncCommit)) + return false; + + writer.incrementState(); + + case 32: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 33: + if (!writer.writeMessage("topVer", topVer)) + 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 20: + accessTtl = reader.readLong("accessTtl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + firstClientReq = reader.readBoolean("firstClientReq"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + hasTransforms = reader.readBoolean("hasTransforms"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + implicitSingleTx = reader.readBoolean("implicitSingleTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 26: + implicitTx = reader.readBoolean("implicitTx"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 27: + miniId = reader.readIgniteUuid("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 28: + onePhaseCommit = reader.readBoolean("onePhaseCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 29: + retVal = reader.readBoolean("retVal"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 30: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 31: + syncCommit = reader.readBoolean("syncCommit"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 32: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 33: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockRequestV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 51; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 34; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockRequestV1.class, this, "filter", Arrays.toString(filter), + "super", super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java new file mode 100644 index 0000000000000..c6c36b5b3131f --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequestV2.java @@ -0,0 +1,487 @@ +package org.apache.ignite.internal.processors.cache.distributed.near; + +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.GridCacheSharedContext; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.transactions.TransactionIsolation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.UUID; + +public class GridNearLockRequestV2 extends GridDistributedLockRequest implements GridNearLockRequest { + /** */ + private static final long serialVersionUID = 0L; + + /** Topology version. */ + private AffinityTopologyVersion topVer; + + /** Mini future ID. */ + private int miniId; + + /** Filter. */ + private CacheEntryPredicate[] filter; + + private byte flags; + + /** Array of mapped DHT versions for this entry. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** Subject ID. */ + private UUID subjId; + + /** Task name hash. */ + private int taskNameHash; + + /** TTL for read operation. */ + private long accessTtl; + + /** + * Empty constructor required for {@link Externalizable}. + */ + public GridNearLockRequestV2() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param topVer Topology version. + * @param nodeId Node ID. + * @param threadId Thread ID. + * @param futId Future ID. + * @param lockVer Cache version. + * @param isInTx {@code True} if implicit transaction lock. + * @param implicitTx Flag to indicate that transaction is implicit. + * @param implicitSingleTx Implicit-transaction-with-one-key flag. + * @param isRead Indicates whether implicit lock is for read or write operation. + * @param retVal Return value flag. + * @param isolation Transaction isolation. + * @param isInvalidate Invalidation flag. + * @param timeout Lock timeout. + * @param keyCnt Number of keys. + * @param txSize Expected transaction size. + * @param syncCommit Synchronous commit flag. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. + * @param accessTtl TTL for read operation. + * @param skipStore Skip store flag. + * @param firstClientReq {@code True} if first lock request for lock operation sent from client node. + * @param addDepInfo Deployment info flag. + */ + public GridNearLockRequestV2( + int cacheId, + @NotNull AffinityTopologyVersion topVer, + UUID nodeId, + long threadId, + IgniteUuid futId, + GridCacheVersion lockVer, + boolean isInTx, + boolean implicitTx, + boolean implicitSingleTx, + boolean isRead, + boolean retVal, + TransactionIsolation isolation, + boolean isInvalidate, + long timeout, + int keyCnt, + int txSize, + boolean syncCommit, + @Nullable UUID subjId, + int taskNameHash, + long accessTtl, + boolean skipStore, + boolean keepBinary, + boolean firstClientReq, + boolean addDepInfo + + ) { + super( + cacheId, + nodeId, + lockVer, + threadId, + futId, + lockVer, + isInTx, + isRead, + isolation, + isInvalidate, + timeout, + keyCnt, + txSize, + skipStore, + keepBinary, + addDepInfo); + + assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; + + this.topVer = topVer; + if (implicitTx) + flags |= 1; + if (implicitSingleTx) + flags |= (1 << 1); + if (syncCommit) + flags |= (1 << 2); + if (retVal) + flags |= (1 << 3); + if (firstClientReq) + flags |= (1 << 4); + + this.subjId = subjId; + this.taskNameHash = taskNameHash; + this.accessTtl = accessTtl; + + dhtVers = new GridCacheVersion[keyCnt]; + } + + /** + * @return {@code True} if first lock request for lock operation sent from client node. + */ + public boolean firstClientRequest() { + return (flags & (1 << 4)) != 0; + } + + /** + * @return Topology version. + */ + @Override public AffinityTopologyVersion topologyVersion() { + return topVer; + } + + /** + * @return Subject ID. + */ + public UUID subjectId() { + return subjId; + } + + /** + * @return Task name hash.q + */ + public int taskNameHash() { + return taskNameHash; + } + + /** + * @return Implicit transaction flag. + */ + public boolean implicitTx() { + return (flags & 1) != 0; + } + + /** + * @return Implicit-transaction-with-one-key flag. + */ + public boolean implicitSingleTx() { + return (flags & (1 << 1)) != 0; + } + + /** + * @return Sync commit flag. + */ + public boolean syncCommit() { + return (flags & (1 << 2)) != 0; + } + + /** + * @return Filter. + */ + public CacheEntryPredicate[] filter() { + return filter; + } + + /** + * @param filter Filter. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + public void filter(CacheEntryPredicate[] filter, GridCacheContext ctx) + throws IgniteCheckedException { + this.filter = filter; + } + + /** + * @return Mini future ID. + */ + public int miniId() { + return miniId; + } + + /** + * @param miniId Mini future Id. + */ + public void miniId(int miniId) { + this.miniId = miniId; + } + + public IgniteUuid oldVersionMiniId() { + return new IgniteUuid(GridNearLockFuture.DUMMY_UUID, miniId); + } + + /** + * @param hasTransforms {@code True} if originating transaction has transform entries. + */ + public void hasTransforms(boolean hasTransforms) { + if (hasTransforms) + flags |= (1 << 5); + else + flags &= ~(1 << 5); + } + + /** + * @return {@code True} if originating transaction has transform entries. + */ + public boolean hasTransforms() { + return (flags & (1 << 5)) != 0; + } + + /** + * @return Need return value flag. + */ + public boolean needReturnValue() { + return (flags & (1 << 3)) != 0; + } + + /** + * Adds a key. + * + * @param key Key. + * @param retVal Flag indicating whether value should be returned. + * @param dhtVer DHT version. + * @param ctx Context. + * @throws IgniteCheckedException If failed. + */ + public void addKeyBytes( + KeyCacheObject key, + boolean retVal, + @Nullable GridCacheVersion dhtVer, + GridCacheContext ctx + ) throws IgniteCheckedException { + dhtVers[idx] = dhtVer; + + // Delegate to super. + addKeyBytes(key, retVal, ctx); + } + + /** + * @param idx Index of the key. + * @return DHT version for key at given index. + */ + public GridCacheVersion dhtVersion(int idx) { + return dhtVers[idx]; + } + + /** + * @return TTL for read operation. + */ + public long accessTtl() { + return accessTtl; + } + + /** {@inheritDoc} */ + @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { + super.prepareMarshal(ctx); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.prepareMarshal(cctx); + } + } + } + + /** {@inheritDoc} */ + @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { + super.finishUnmarshal(ctx, ldr); + + if (filter != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + for (CacheEntryPredicate p : filter) { + if (p != null) + p.finishUnmarshal(cctx, ldr); + } + } + } + + /** {@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 20: + if (!writer.writeLong("accessTtl", accessTtl)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeObjectArray("filter", filter, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeByte("flags", flags)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeInt("miniId", miniId)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeUuid("subjId", subjId)) + return false; + + writer.incrementState(); + + case 26: + if (!writer.writeInt("taskNameHash", taskNameHash)) + return false; + + writer.incrementState(); + + case 27: + if (!writer.writeMessage("topVer", topVer)) + 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 20: + accessTtl = reader.readLong("accessTtl"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + filter = reader.readObjectArray("filter", MessageCollectionItemType.MSG, CacheEntryPredicate.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + flags = reader.readByte("flags"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + miniId = reader.readInt("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + subjId = reader.readUuid("subjId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 26: + taskNameHash = reader.readInt("taskNameHash"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 27: + topVer = reader.readMessage("topVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockRequestV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 125; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 28; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockRequestV2.class, this, "filter", Arrays.toString(filter), + "super", super.toString()); + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java index e48a09894164a..8378d4b4ba208 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java @@ -1,330 +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.internal.processors.cache.distributed.near; -import java.io.Externalizable; -import java.nio.ByteBuffer; -import java.util.Collection; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.GridDirectCollection; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; -import org.apache.ignite.plugin.extensions.communication.MessageReader; -import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; -/** - * Near cache lock response. - */ -public class GridNearLockResponse extends GridDistributedLockResponse { - /** */ - private static final long serialVersionUID = 0L; - - /** Collection of versions that are pending and less than lock version. */ - @GridToStringInclude - @GridDirectCollection(GridCacheVersion.class) - private Collection pending; - - /** */ - private IgniteUuid miniId; - - /** DHT versions. */ - @GridToStringInclude - private GridCacheVersion[] dhtVers; - - /** DHT candidate versions. */ - @GridToStringInclude - private GridCacheVersion[] mappedVers; - - /** Filter evaluation results for fast-commit transactions. */ - private boolean[] filterRes; - - /** {@code True} if client node should remap lock request. */ - private AffinityTopologyVersion clientRemapVer; - - /** - * Empty constructor (required by {@link Externalizable}). - */ - public GridNearLockResponse() { - // No-op. - } - - /** - * @param cacheId Cache ID. - * @param lockVer Lock ID. - * @param futId Future ID. - * @param miniId Mini future ID. - * @param filterRes {@code True} if need to allocate array for filter evaluation results. - * @param cnt Count. - * @param err Error. - * @param clientRemapVer {@code True} if client node should remap lock request. - * @param addDepInfo Deployment info. - */ - public GridNearLockResponse( - int cacheId, - GridCacheVersion lockVer, - IgniteUuid futId, - IgniteUuid miniId, - boolean filterRes, - int cnt, - Throwable err, - AffinityTopologyVersion clientRemapVer, - boolean addDepInfo - ) { - super(cacheId, lockVer, futId, cnt, err, addDepInfo); - - assert miniId != null; - - this.miniId = miniId; - this.clientRemapVer = clientRemapVer; - - dhtVers = new GridCacheVersion[cnt]; - mappedVers = new GridCacheVersion[cnt]; - - if (filterRes) - this.filterRes = new boolean[cnt]; - } - - /** - * @return {@code True} if client node should remap lock request. - */ - @Nullable public AffinityTopologyVersion clientRemapVersion() { - return clientRemapVer; - } - - /** - * Gets pending versions that are less than {@link #version()}. - * - * @return Pending versions. - */ - public Collection pending() { - return pending; - } +import java.util.Collection; - /** - * Sets pending versions that are less than {@link #version()}. - * - * @param pending Pending versions. - */ - public void pending(Collection pending) { - this.pending = pending; - } +public interface GridNearLockResponse extends Message, GridCacheDeployable, GridCacheVersionable { + @Nullable AffinityTopologyVersion clientRemapVersion(); - /** - * @return Mini future ID. - */ - public IgniteUuid miniId() { - return miniId; - } + Collection pending(); - /** - * @param idx Index. - * @return DHT version. - */ - public GridCacheVersion dhtVersion(int idx) { - return dhtVers == null ? null : dhtVers[idx]; - } + void pending(Collection pending); - /** - * Returns DHT candidate version for acquired near lock on DHT node. - * - * @param idx Key index. - * @return DHT version. - */ - public GridCacheVersion mappedVersion(int idx) { - return mappedVers == null ? null : mappedVers[idx]; - } + GridCacheVersion dhtVersion(int idx); - /** - * Gets filter evaluation result for fast-commit transaction. - * - * @param idx Result index. - * @return {@code True} if filter passed on primary node, {@code false} otherwise. - */ - public boolean filterResult(int idx) { - assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + GridCacheVersion mappedVersion(int idx); - return filterRes[idx]; - } + boolean filterResult(int idx); - /** - * @param val Value. - * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. - * @param dhtVer DHT version. - * @param mappedVer Mapped version. - * @throws IgniteCheckedException If failed. - */ - public void addValueBytes( + void addValueBytes( @Nullable CacheObject val, boolean filterPassed, @Nullable GridCacheVersion dhtVer, @Nullable GridCacheVersion mappedVer - ) throws IgniteCheckedException { - int idx = valuesSize(); - - dhtVers[idx] = dhtVer; - mappedVers[idx] = mappedVer; - - if (filterRes != null) - filterRes[idx] = filterPassed; - - // Delegate to super. - addValue(val); - } - - /** {@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 10: - if (!writer.writeMessage("clientRemapVer", clientRemapVer)) - return false; - - writer.incrementState(); - - case 11: - if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 12: - if (!writer.writeBooleanArray("filterRes", filterRes)) - return false; - - writer.incrementState(); - - case 13: - if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) - return false; - - writer.incrementState(); - - case 14: - if (!writer.writeIgniteUuid("miniId", miniId)) - return false; - - writer.incrementState(); - - case 15: - if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) - 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 10: - clientRemapVer = reader.readMessage("clientRemapVer"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 11: - dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 12: - filterRes = reader.readBooleanArray("filterRes"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 13: - mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 14: - miniId = reader.readIgniteUuid("miniId"); - - if (!reader.isLastRead()) - return false; - - reader.incrementState(); - - case 15: - pending = reader.readCollection("pending", MessageCollectionItemType.MSG); + ) throws IgniteCheckedException; - if (!reader.isLastRead()) - return false; + CacheObject value(int idx); - reader.incrementState(); + Throwable error(); - } + Collection committedVersions(); - return reader.afterMessageRead(GridNearLockResponse.class); - } + Collection rolledbackVersions(); - /** {@inheritDoc} */ - @Override public byte directType() { - return 52; - } + IgniteUuid futureId(); - /** {@inheritDoc} */ - @Override public byte fieldsCount() { - return 16; - } + void completedVersions(Collection committedVers, Collection rolledbackVers); - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(GridNearLockResponse.class, this, super.toString()); - } + void error(Throwable err); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java new file mode 100644 index 0000000000000..98a379fcae96b --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV1.java @@ -0,0 +1,330 @@ +/* + * 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.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Collection; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.jetbrains.annotations.Nullable; + +/** + * Near cache lock response. + */ +public class GridNearLockResponseV1 extends GridDistributedLockResponse implements GridNearLockResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Collection of versions that are pending and less than lock version. */ + @GridToStringInclude + @GridDirectCollection(GridCacheVersion.class) + private Collection pending; + + /** */ + private IgniteUuid miniId; + + /** DHT versions. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** DHT candidate versions. */ + @GridToStringInclude + private GridCacheVersion[] mappedVers; + + /** Filter evaluation results for fast-commit transactions. */ + private boolean[] filterRes; + + /** {@code True} if client node should remap lock request. */ + private AffinityTopologyVersion clientRemapVer; + + /** + * Empty constructor (required by {@link Externalizable}). + */ + public GridNearLockResponseV1() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param lockVer Lock ID. + * @param futId Future ID. + * @param miniId Mini future ID. + * @param filterRes {@code True} if need to allocate array for filter evaluation results. + * @param cnt Count. + * @param err Error. + * @param clientRemapVer {@code True} if client node should remap lock request. + * @param addDepInfo Deployment info. + */ + public GridNearLockResponseV1( + int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + IgniteUuid miniId, + boolean filterRes, + int cnt, + Throwable err, + AffinityTopologyVersion clientRemapVer, + boolean addDepInfo + ) { + super(cacheId, lockVer, futId, cnt, err, addDepInfo); + + assert miniId != null; + + this.miniId = miniId; + this.clientRemapVer = clientRemapVer; + + dhtVers = new GridCacheVersion[cnt]; + mappedVers = new GridCacheVersion[cnt]; + + if (filterRes) + this.filterRes = new boolean[cnt]; + } + + /** + * @return {@code True} if client node should remap lock request. + */ + @Override @Nullable public AffinityTopologyVersion clientRemapVersion() { + return clientRemapVer; + } + + /** + * Gets pending versions that are less than {@link #version()}. + * + * @return Pending versions. + */ + @Override public Collection pending() { + return pending; + } + + /** + * Sets pending versions that are less than {@link #version()}. + * + * @param pending Pending versions. + */ + @Override public void pending(Collection pending) { + this.pending = pending; + } + + /** + * @return Mini future ID. + */ + public IgniteUuid miniId() { + return miniId; + } + + /** + * @param idx Index. + * @return DHT version. + */ + @Override public GridCacheVersion dhtVersion(int idx) { + return dhtVers == null ? null : dhtVers[idx]; + } + + /** + * Returns DHT candidate version for acquired near lock on DHT node. + * + * @param idx Key index. + * @return DHT version. + */ + @Override public GridCacheVersion mappedVersion(int idx) { + return mappedVers == null ? null : mappedVers[idx]; + } + + /** + * Gets filter evaluation result for fast-commit transaction. + * + * @param idx Result index. + * @return {@code True} if filter passed on primary node, {@code false} otherwise. + */ + @Override public boolean filterResult(int idx) { + assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + + return filterRes[idx]; + } + + /** + * @param val Value. + * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. + * @param dhtVer DHT version. + * @param mappedVer Mapped version. + * @throws IgniteCheckedException If failed. + */ + @Override public void addValueBytes( + @Nullable CacheObject val, + boolean filterPassed, + @Nullable GridCacheVersion dhtVer, + @Nullable GridCacheVersion mappedVer + ) throws IgniteCheckedException { + int idx = valuesSize(); + + dhtVers[idx] = dhtVer; + mappedVers[idx] = mappedVer; + + if (filterRes != null) + filterRes[idx] = filterPassed; + + // Delegate to super. + addValue(val); + } + + /** {@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 10: + if (!writer.writeMessage("clientRemapVer", clientRemapVer)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBooleanArray("filterRes", filterRes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeIgniteUuid("miniId", miniId)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) + 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 10: + clientRemapVer = reader.readMessage("clientRemapVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + filterRes = reader.readBooleanArray("filterRes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + miniId = reader.readIgniteUuid("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + pending = reader.readCollection("pending", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockResponseV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 52; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 16; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockResponseV1.class, this, super.toString()); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java new file mode 100644 index 0000000000000..d2110140a36aa --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponseV2.java @@ -0,0 +1,310 @@ +package org.apache.ignite.internal.processors.cache.distributed.near; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridDirectCollection; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockResponse; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +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.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; +import org.jetbrains.annotations.Nullable; + +import java.io.Externalizable; +import java.nio.ByteBuffer; +import java.util.Collection; + +public class GridNearLockResponseV2 extends GridDistributedLockResponse implements GridNearLockResponse { + /** */ + private static final long serialVersionUID = 0L; + + /** Collection of versions that are pending and less than lock version. */ + @GridToStringInclude + @GridDirectCollection(GridCacheVersion.class) + private Collection pending; + + /** */ + private int miniId; + + /** DHT versions. */ + @GridToStringInclude + private GridCacheVersion[] dhtVers; + + /** DHT candidate versions. */ + @GridToStringInclude + private GridCacheVersion[] mappedVers; + + /** Filter evaluation results for fast-commit transactions. */ + private boolean[] filterRes; + + /** {@code True} if client node should remap lock request. */ + private AffinityTopologyVersion clientRemapVer; + + /** + * Empty constructor (required by {@link Externalizable}). + */ + public GridNearLockResponseV2() { + // No-op. + } + + /** + * @param cacheId Cache ID. + * @param lockVer Lock ID. + * @param futId Future ID. + * @param miniId Mini future ID. + * @param filterRes {@code True} if need to allocate array for filter evaluation results. + * @param cnt Count. + * @param err Error. + * @param clientRemapVer {@code True} if client node should remap lock request. + * @param addDepInfo Deployment info. + */ + public GridNearLockResponseV2( + int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + int miniId, + boolean filterRes, + int cnt, + Throwable err, + AffinityTopologyVersion clientRemapVer, + boolean addDepInfo + ) { + super(cacheId, lockVer, futId, cnt, err, addDepInfo); + + this.miniId = miniId; + this.clientRemapVer = clientRemapVer; + + dhtVers = new GridCacheVersion[cnt]; + mappedVers = new GridCacheVersion[cnt]; + + if (filterRes) + this.filterRes = new boolean[cnt]; + } + + /** + * @return {@code True} if client node should remap lock request. + */ + @Nullable public AffinityTopologyVersion clientRemapVersion() { + return clientRemapVer; + } + + /** + * Gets pending versions that are less than {@link #version()}. + * + * @return Pending versions. + */ + public Collection pending() { + return pending; + } + + /** + * Sets pending versions that are less than {@link #version()}. + * + * @param pending Pending versions. + */ + public void pending(Collection pending) { + this.pending = pending; + } + + /** + * @return Mini future ID. + */ + public int miniId() { + return miniId; + } + + /** + * @param idx Index. + * @return DHT version. + */ + public GridCacheVersion dhtVersion(int idx) { + return dhtVers == null ? null : dhtVers[idx]; + } + + /** + * Returns DHT candidate version for acquired near lock on DHT node. + * + * @param idx Key index. + * @return DHT version. + */ + public GridCacheVersion mappedVersion(int idx) { + return mappedVers == null ? null : mappedVers[idx]; + } + + /** + * Gets filter evaluation result for fast-commit transaction. + * + * @param idx Result index. + * @return {@code True} if filter passed on primary node, {@code false} otherwise. + */ + public boolean filterResult(int idx) { + assert filterRes != null : "Should not call filterResult for non-fast-commit transactions."; + + return filterRes[idx]; + } + + /** + * @param val Value. + * @param filterPassed Boolean flag indicating whether filter passed for fast-commit transaction. + * @param dhtVer DHT version. + * @param mappedVer Mapped version. + * @throws IgniteCheckedException If failed. + */ + public void addValueBytes( + @Nullable CacheObject val, + boolean filterPassed, + @Nullable GridCacheVersion dhtVer, + @Nullable GridCacheVersion mappedVer + ) throws IgniteCheckedException { + int idx = valuesSize(); + + dhtVers[idx] = dhtVer; + mappedVers[idx] = mappedVer; + + if (filterRes != null) + filterRes[idx] = filterPassed; + + // Delegate to super. + addValue(val); + } + + /** {@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 10: + if (!writer.writeMessage("clientRemapVer", clientRemapVer)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeObjectArray("dhtVers", dhtVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeBooleanArray("filterRes", filterRes)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeObjectArray("mappedVers", mappedVers, MessageCollectionItemType.MSG)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeInt("miniId", miniId)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeCollection("pending", pending, MessageCollectionItemType.MSG)) + 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 10: + clientRemapVer = reader.readMessage("clientRemapVer"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + dhtVers = reader.readObjectArray("dhtVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + filterRes = reader.readBooleanArray("filterRes"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + mappedVers = reader.readObjectArray("mappedVers", MessageCollectionItemType.MSG, GridCacheVersion.class); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + miniId = reader.readInt("miniId"); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + pending = reader.readCollection("pending", MessageCollectionItemType.MSG); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + } + + return reader.afterMessageRead(GridNearLockResponseV1.class); + } + + /** {@inheritDoc} */ + @Override public byte directType() { + return 126; + } + + /** {@inheritDoc} */ + @Override public byte fieldsCount() { + return 16; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridNearLockResponseV2.class, this, super.toString()); + } +} + 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 d5483cd12fcb6..1f6cfef711a27 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 @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import org.apache.ignite.IgniteCheckedException; @@ -81,6 +82,8 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim @GridToStringExclude private ClientRemapFuture remapFut; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Context. * @param tx Transaction. @@ -228,7 +231,7 @@ private void onError(@Nullable GridDistributedTxMapping m, Throwable e) { * @return Mini future. */ @SuppressWarnings("ForLoopReplaceableByForEach") - private MiniFuture miniFuture(IgniteUuid miniId) { + private MiniFuture miniFuture(int miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (futs) { // Avoid iterator creation. @@ -240,7 +243,7 @@ private MiniFuture miniFuture(IgniteUuid miniId) { MiniFuture mini = (MiniFuture)fut; - if (mini.futureId().equals(miniId)) { + if (mini.miniId() == miniId) { if (!mini.isDone()) return mini; else @@ -462,7 +465,7 @@ private boolean skipFuture(boolean remap, IgniteInternalFuture fut) { } } - req.miniId(fut.futureId()); + req.miniId(fut.miniId()); // If this is the primary node for the keys. if (n.isLocal()) { @@ -674,16 +677,16 @@ private static class ClientRemapFutureReducer implements IgniteReducer { + private class MiniFuture extends GridFutureAdapter { /** */ private static final long serialVersionUID = 0L; /** Receive result flag updater. */ - private static AtomicIntegerFieldUpdater RCV_RES_UPD = + private AtomicIntegerFieldUpdater RCV_RES_UPD = AtomicIntegerFieldUpdater.newUpdater(MiniFuture.class, "rcvRes"); /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** Parent future. */ private final GridNearOptimisticSerializableTxPrepareFuture parent; @@ -708,8 +711,8 @@ private static class MiniFuture extends GridFutureAdapter { + private class MiniFuture extends GridFutureAdapter { /** */ private static final long serialVersionUID = 0L; /** Receive result flag updater. */ - private static AtomicIntegerFieldUpdater RCV_RES_UPD = + private AtomicIntegerFieldUpdater RCV_RES_UPD = AtomicIntegerFieldUpdater.newUpdater(MiniFuture.class, "rcvRes"); /** Parent future. */ private final GridNearOptimisticTxPrepareFuture parent; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** Keys. */ @GridToStringInclude @@ -658,8 +661,8 @@ private static class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** */ private GridDistributedTxMapping m; @@ -337,8 +341,8 @@ private class MiniFuture extends GridFutureAdapter { /** * @return Future ID. */ - IgniteUuid futureId() { - return futId; + int miniId() { + return miniId; } /** 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 a3130cdd0b053..367e9df831119 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 @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; + import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; @@ -94,8 +95,14 @@ public GridNearTransactionalCache(GridCacheContext ctx) { } }); - ctx.io().addHandler(ctx.cacheId(), GridNearLockResponse.class, new CI2() { - @Override public void apply(UUID nodeId, GridNearLockResponse res) { + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV1.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV1 res) { + processLockResponse(nodeId, res); + } + }); + + ctx.io().addHandler(ctx.cacheId(), GridNearLockResponseV2.class, new CI2() { + @Override public void apply(UUID nodeId, GridNearLockResponseV2 res) { processLockResponse(nodeId, res); } }); 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 a70fb3a9b7988..ebfe584ff7f81 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 @@ -961,7 +961,7 @@ public IgniteInternalFuture prepareAsyncLocal( GridDhtTxPrepareFuture fut = new GridDhtTxPrepareFuture( cctx, this, - IgniteUuid.randomUuid(), + 0, Collections.emptyMap(), last, needReturnValue() && implicit()); 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 9dfdb43e3c0f5..2274086381768 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 @@ -49,7 +49,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest { private IgniteUuid futId; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** Near mapping flag. */ private boolean near; @@ -175,14 +175,14 @@ public IgniteUuid futureId() { /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } /** * @param miniId Mini future ID. */ - public void miniId(IgniteUuid miniId) { + public void miniId(int miniId) { this.miniId = miniId; } @@ -319,7 +319,7 @@ private Collection cloneEntries(Collection c) { writer.incrementState(); case 29: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -419,7 +419,7 @@ private Collection cloneEntries(Collection c) { reader.incrementState(); case 29: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java index 8812709c6d49e..4179211cccee9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java @@ -61,7 +61,7 @@ public class GridNearTxPrepareResponse extends GridDistributedTxPrepareResponse private IgniteUuid futId; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** DHT version. */ private GridCacheVersion dhtVer; @@ -120,7 +120,7 @@ public GridNearTxPrepareResponse() { public GridNearTxPrepareResponse( GridCacheVersion xid, IgniteUuid futId, - IgniteUuid miniId, + int miniId, GridCacheVersion dhtVer, GridCacheVersion writeVer, GridCacheReturn retVal, @@ -131,7 +131,6 @@ public GridNearTxPrepareResponse( super(xid, err, addDepInfo); assert futId != null; - assert miniId != null; assert dhtVer != null; this.futId = futId; @@ -170,7 +169,7 @@ public void pending(Collection pending) { /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -386,7 +385,7 @@ public Collection invalidPartitions() { writer.incrementState(); case 13: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -478,7 +477,7 @@ public Collection invalidPartitions() { reader.incrementState(); case 13: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java index 13cac81cab558..f45086bb12e58 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectAtomicsTest.java @@ -29,7 +29,7 @@ import org.apache.ignite.IgniteClientDisconnectedException; import org.apache.ignite.IgniteCountDownLatch; import org.apache.ignite.IgniteSemaphore; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.testframework.GridTestUtils; /** @@ -202,7 +202,7 @@ public void testAtomicSeqReconnectInProgress() throws Exception { srvAtomicSeq.batchSize(1); - commSpi.blockMessage(GridNearLockResponse.class); + commSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -362,7 +362,7 @@ public void testAtomicReferenceReconnectInProgress() throws Exception { BlockTpcCommunicationSpi servCommSpi = commSpi(srv); - servCommSpi.blockMessage(GridNearLockResponse.class); + servCommSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -522,7 +522,7 @@ public void testAtomicStampedReconnectInProgress() throws Exception { BlockTpcCommunicationSpi servCommSpi = commSpi(srv); - servCommSpi.blockMessage(GridNearLockResponse.class); + servCommSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -654,7 +654,7 @@ public void testAtomicLongReconnectInProgress() throws Exception { final IgniteAtomicLong srvAtomicLong = srv.atomicLong("atomicLongInProggress", 0, false); - commSpi.blockMessage(GridNearLockResponse.class); + commSpi.blockMessage(GridNearLockResponseV1.class); final IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java index 37937d318427b..ac4912aa4ccdf 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java @@ -49,10 +49,10 @@ import org.apache.ignite.events.Event; import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponseV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse; @@ -557,7 +557,7 @@ public void testReconnectTransactionInProgress2() throws Exception { txInProgressFails(client, ccfg, GridNearTxFinishResponse.class, PESSIMISTIC, 4); - txInProgressFails(client, ccfg, GridNearLockResponse.class, PESSIMISTIC, 5); + txInProgressFails(client, ccfg, GridNearLockResponseV1.class, PESSIMISTIC, 5); } /** @@ -806,7 +806,7 @@ else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) if (syncMode != FULL_ASYNC) { Class cls = (ccfg.getAtomicityMode() == ATOMIC) ? - GridNearAtomicMultipleUpdateResponse.class : GridNearTxPrepareResponse.class; + GridNearAtomicUpdateResponse.class : GridNearTxPrepareResponse.class; log.info("Test cache put [atomicity=" + atomicityMode + ", writeOrder=" + writeOrder + diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java index d25ac37025974..100e8de4a4a36 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCollectionsTest.java @@ -26,7 +26,7 @@ import org.apache.ignite.IgniteQueue; import org.apache.ignite.IgniteSet; import org.apache.ignite.configuration.CollectionConfiguration; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateResponse; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse; import org.apache.ignite.testframework.GridTestUtils; @@ -315,7 +315,7 @@ private void setReconnectInProgress(final CollectionConfiguration colCfg) throws BlockTpcCommunicationSpi commSpi = commSpi(srv); if (colCfg.getAtomicityMode() == ATOMIC) - commSpi.blockMessage(GridNearAtomicMultipleUpdateResponse.class); + commSpi.blockMessage(GridNearAtomicUpdateResponse.class); else commSpi.blockMessage(GridNearTxPrepareResponse.class); @@ -457,7 +457,7 @@ private void queueReconnectInProgress(final CollectionConfiguration colCfg) thro BlockTpcCommunicationSpi commSpi = commSpi(srv); if (colCfg.getAtomicityMode() == ATOMIC) - commSpi.blockMessage(GridNearAtomicMultipleUpdateResponse.class); + commSpi.blockMessage(GridNearAtomicUpdateResponse.class); else commSpi.blockMessage(GridNearTxPrepareResponse.class); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java index 0633a1e247f42..0e17102daea78 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicMessageCountSelfTest.java @@ -27,9 +27,8 @@ import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.managers.communication.GridIoMessage; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicMultipleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiException; @@ -138,9 +137,8 @@ protected void checkMessages(boolean clientMode, TestCommunicationSpi commSpi = (TestCommunicationSpi)grid(0).configuration().getCommunicationSpi(); - commSpi.registerMessage(GridNearAtomicMultipleUpdateRequest.class); - commSpi.registerMessage(GridNearAtomicSingleUpdateRequest.class); - commSpi.registerMessage(GridDhtAtomicMultipleUpdateRequest.class); + commSpi.registerMessage(GridNearAtomicUpdateRequest.class); + commSpi.registerMessage(GridDhtAtomicUpdateRequest.class); int putCnt = 15; @@ -168,22 +166,22 @@ protected void checkMessages(boolean clientMode, jcache(0).put(i, i); } - assertEquals(expNearCnt, nearRequestsCount(commSpi)); - assertEquals(expDhtCnt, dhtRequestsCount(commSpi)); + assertEquals(expNearCnt, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); + assertEquals(expDhtCnt, commSpi.messageCount(GridDhtAtomicUpdateRequest.class)); if (writeOrderMode == CLOCK) { for (int i = 1; i < 4; i++) { commSpi = (TestCommunicationSpi)grid(i).configuration().getCommunicationSpi(); - assertEquals(0, nearRequestsCount(commSpi)); - assertEquals(0, dhtRequestsCount(commSpi)); + assertEquals(0, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); + assertEquals(0, commSpi.messageCount(GridDhtAtomicUpdateRequest.class)); } } else { for (int i = 1; i < 4; i++) { commSpi = (TestCommunicationSpi)grid(i).configuration().getCommunicationSpi(); - assertEquals(0, nearRequestsCount(commSpi)); + assertEquals(0, commSpi.messageCount(GridNearAtomicUpdateRequest.class)); } } } @@ -192,27 +190,6 @@ protected void checkMessages(boolean clientMode, } } - /** - * Get amount of near update requests. - * - * @param commSpi Communication SPI. - * @return Count. - */ - private int nearRequestsCount(TestCommunicationSpi commSpi) { - return commSpi.messageCount(GridNearAtomicMultipleUpdateRequest.class) + - commSpi.messageCount(GridNearAtomicSingleUpdateRequest.class); - } - - /** - * Get amount of DHT update requests. - * - * @param commSpi Communication SPI. - * @return Count. - */ - private int dhtRequestsCount(TestCommunicationSpi commSpi) { - return commSpi.messageCount(GridDhtAtomicMultipleUpdateRequest.class); - } - /** * Test communication SPI. */ @@ -252,5 +229,12 @@ public int messageCount(Class cls) { return cntr == null ? 0 : cntr.get(); } + + /** + * Resets counter to zero. + */ + public void resetCount() { + cntMap.clear(); + } } } \ No newline at end of file diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java index 43a111a61af5a..cdb7907330d9f 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicStopBusySelfTest.java @@ -18,8 +18,7 @@ package org.apache.ignite.internal.processors.cache; import org.apache.ignite.cache.CacheAtomicityMode; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; +import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; /** * Stopped node when client operations are executing. @@ -32,32 +31,28 @@ public class IgniteCacheAtomicStopBusySelfTest extends IgniteCacheAbstractStopBu /** {@inheritDoc} */ @Override public void testPut() throws Exception { - bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); - bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); + bannedMsg.set(GridNearAtomicUpdateRequest.class); super.testPut(); } /** {@inheritDoc} */ @Override public void testPutBatch() throws Exception { - bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); - bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); + bannedMsg.set(GridNearAtomicUpdateRequest.class); super.testPut(); } /** {@inheritDoc} */ @Override public void testPutAsync() throws Exception { - bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); - bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); + bannedMsg.set(GridNearAtomicUpdateRequest.class); super.testPut(); } /** {@inheritDoc} */ @Override public void testRemove() throws Exception { - bannedMsg.set(GridNearAtomicMultipleUpdateRequest.class); - bannedMsg.set(GridNearAtomicSingleUpdateRequest.class); + bannedMsg.set(GridNearAtomicUpdateRequest.class); super.testPut(); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java index f106fecca3361..1089ea1293ccd 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheNearLockValueSelfTest.java @@ -26,7 +26,7 @@ import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.TestRecordingCommunicationSpi; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; 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; @@ -66,7 +66,7 @@ public class IgniteCacheNearLockValueSelfTest extends GridCommonAbstractTest { TestRecordingCommunicationSpi commSpi = new TestRecordingCommunicationSpi(); - commSpi.record(GridNearLockRequest.class); + commSpi.record(GridNearLockRequestV1.class); cfg.setCommunicationSpi(commSpi); @@ -94,7 +94,7 @@ public void testDhtVersion() throws Exception { TestRecordingCommunicationSpi comm = (TestRecordingCommunicationSpi)ignite(0).configuration().getCommunicationSpi(); - Collection reqs = (Collection)comm.recordedMessages(); + Collection reqs = (Collection)comm.recordedMessages(); assertEquals(1, reqs.size()); @@ -104,7 +104,7 @@ public void testDhtVersion() throws Exception { assertNotNull(dhtEntry); - GridNearLockRequest req = reqs.iterator().next(); + GridNearLockRequestV1 req = reqs.iterator().next(); assertEquals(dhtEntry.version(), req.dhtVersion(0)); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java index cfa1244ee5273..5c283160bb748 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxReentryAbstractSelfTest.java @@ -29,7 +29,7 @@ import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockRequest; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiException; @@ -158,7 +158,7 @@ private void countMsg(GridIoMessage msg) { if (origMsg instanceof GridDistributedLockRequest) { distLocks.incrementAndGet(); - if (origMsg instanceof GridNearLockRequest) + if (origMsg instanceof GridNearLockRequestV1) nearLocks.incrementAndGet(); else if (origMsg instanceof GridDhtLockRequest) dhtLocks.incrementAndGet(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java index 49686fc87f300..280ab71ee08bc 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java @@ -61,12 +61,10 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter; import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager; import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateRequest; -import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicMultipleUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry; -import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest; +import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequestV1; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.lang.GridAbsPredicate; @@ -108,7 +106,6 @@ /** * */ -@SuppressWarnings({"unchecked", "unused", "NullArgumentToVariableArgMethod", "ConstantConditions", "UnusedAssignment"}) public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstractTest { /** */ protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); @@ -233,11 +230,8 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -278,8 +272,7 @@ private void atomicPut(CacheAtomicWriteOrderMode writeOrder, map.put(i, i + 1); // Block messages requests for single node. - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); putFut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -366,16 +359,11 @@ private void atomicNoRemap(CacheAtomicWriteOrderMode writeOrder) throws Exceptio TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); - - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite2.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite2.localNode().id()); - spi.record(GridNearAtomicMultipleUpdateRequest.class, GridNearAtomicSingleUpdateRequest.class); + spi.record(GridNearAtomicUpdateRequest.class); final IgniteCache cache = ignite3.cache(null); @@ -469,11 +457,8 @@ private void atomicGetAndPut(CacheAtomicWriteOrderMode writeOrder) throws Except TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); // Block messages requests for both nodes. - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite0.localNode().id()); - - spi.blockMessages(GridNearAtomicMultipleUpdateRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearAtomicSingleUpdateRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite0.localNode().id()); + spi.blockMessages(GridNearAtomicUpdateRequest.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -614,10 +599,10 @@ private void pessimisticTx(NearCacheConfiguration nearCfg) throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); final IgniteCache cache = ignite2.cache(null); @@ -653,19 +638,19 @@ private void pessimisticTx(NearCacheConfiguration nearCfg) throws Exception { List msgs = spi.recordedMessages(); - assertTrue(((GridNearLockRequest)msgs.get(0)).firstClientRequest()); - assertTrue(((GridNearLockRequest)msgs.get(1)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(0)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(1)).firstClientRequest()); for (int i = 2; i < msgs.size(); i++) - assertFalse(((GridNearLockRequest)msgs.get(i)).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msgs.get(i)).firstClientRequest()); ignite3.close(); for (int i = 0; i < 100; i++) map.put(i, i + 1); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); putFut = GridTestUtils.runAsync(new Callable() { @Override public Object call() throws Exception { @@ -827,9 +812,9 @@ public void testPessimisticTx2() throws Exception { final Integer key1 = keys.get1(); final Integer key2 = keys.get2(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite2.localNode().id()); final IgniteCache cache = ignite3.cache(null); @@ -927,11 +912,11 @@ private void pessimisticTxNoRemap(@Nullable NearCacheConfiguration nearCfg) thro for (int i = 0; i < 100; i++) map.put(i, i); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite2.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite2.localNode().id()); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); final IgniteCache cache = ignite3.cache(null); @@ -1170,8 +1155,8 @@ private void lock(NearCacheConfiguration nearCfg) throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi(); - spi.blockMessages(GridNearLockRequest.class, ignite0.localNode().id()); - spi.blockMessages(GridNearLockRequest.class, ignite1.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite0.localNode().id()); + spi.blockMessages(GridNearLockRequestV1.class, ignite1.localNode().id()); final IgniteCache cache = ignite2.cache(null); @@ -1278,7 +1263,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi(); - spi.record(GridNearLockRequest.class); + spi.record(GridNearLockRequestV1.class); IgniteCache cache = ignite3.cache(null); @@ -1317,7 +1302,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { TestCommunicationSpi spi0 = (TestCommunicationSpi)ignite0.configuration().getCommunicationSpi(); - spi0.record(GridNearLockRequest.class); + spi0.record(GridNearLockRequestV1.class); List keys = primaryKeys(ignite1.cache(null), 3, 0); @@ -1336,7 +1321,7 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { assertEquals(3, msgs.size()); for (Object msg : msgs) - assertFalse(((GridNearLockRequest)msg).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msg).firstClientRequest()); } /** @@ -1346,10 +1331,10 @@ public void testPessimisticTxMessageClientFirstFlag() throws Exception { private void checkClientLockMessages(List msgs, int expCnt) { assertEquals(expCnt, msgs.size()); - assertTrue(((GridNearLockRequest)msgs.get(0)).firstClientRequest()); + assertTrue(((GridNearLockRequestV1)msgs.get(0)).firstClientRequest()); for (int i = 1; i < msgs.size(); i++) - assertFalse(((GridNearLockRequest)msgs.get(i)).firstClientRequest()); + assertFalse(((GridNearLockRequestV1)msgs.get(i)).firstClientRequest()); } /** @@ -2019,7 +2004,7 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { private Map, Set> blockCls = new HashMap<>(); /** */ - private Class[] recordClss; + private Class recordCls; /** */ private List recordedMsgs = new ArrayList<>(); @@ -2031,7 +2016,7 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { Object msg0 = ((GridIoMessage)msg).message(); synchronized (this) { - if (isRecordMessage(msg0.getClass())) + if (recordCls != null && msg0.getClass().equals(recordCls)) recordedMsgs.add(msg0); Set blockNodes = blockCls.get(msg0.getClass()); @@ -2053,9 +2038,9 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi { /** * @param recordCls Message class to record. */ - void record(@Nullable Class... recordCls) { + void record(@Nullable Class recordCls) { synchronized (this) { - this.recordClss = recordCls; + this.recordCls = recordCls; } } @@ -2109,23 +2094,6 @@ void stopBlock() { blockedMsgs.clear(); } } - - /** - * Decide whether to record message or not. - * - * @param msgCls Message class. - * @return {@code True} if message should be recorded. - */ - private boolean isRecordMessage(Class msgCls) { - if (recordClss != null) { - for (Class recordCls : recordClss) { - if (msgCls.equals(recordCls)) - return true; - } - } - - return false; - } } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java index e3adc21f26207..74d2d09812e07 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java @@ -477,11 +477,8 @@ private static class DelayCommunicationSpi extends TcpCommunicationSpi { private boolean delayMessage(GridIoMessage msg) { Object origMsg = msg.message(); - return delay && ( - (origMsg instanceof GridNearAtomicMultipleUpdateRequest) || - (origMsg instanceof GridNearAtomicSingleUpdateRequest) || - (origMsg instanceof GridDhtAtomicMultipleUpdateRequest) - ); + return delay && + ((origMsg instanceof GridNearAtomicUpdateRequest) || (origMsg instanceof GridDhtAtomicUpdateRequest)); } } } \ No newline at end of file From 25b5fbb58417e72c30728a225cd74d63f09852d5 Mon Sep 17 00:00:00 2001 From: Ilya Lantukh Date: Sat, 20 Feb 2016 11:03:21 +0300 Subject: [PATCH 34/34] TX finish request/response optimizations. --- .../dht/GridDhtTxFinishFuture.java | 17 +++++++------ .../dht/GridDhtTxFinishRequest.java | 13 +++++----- .../dht/GridDhtTxFinishResponse.java | 12 ++++----- .../cache/distributed/dht/GridDhtTxLocal.java | 6 ++--- .../near/GridNearTxFinishFuture.java | 25 +++++++++++-------- .../near/GridNearTxFinishRequest.java | 10 ++++---- .../near/GridNearTxFinishResponse.java | 12 ++++----- 7 files changed, 48 insertions(+), 47 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java index 8c295ce74db3d..7e0cf3f9ffabe 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; @@ -93,6 +94,8 @@ public final class GridDhtTxFinishFuture extends GridCompoundIdentityFutur /** Trackable flag. */ private boolean trackable = true; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Context. * @param tx Transaction. @@ -190,7 +193,7 @@ public void onResult(UUID nodeId, GridDhtTxFinishResponse res) { if (isMini(fut)) { MiniFuture f = (MiniFuture)fut; - if (f.futureId().equals(res.miniId())) { + if (f.miniId() == res.miniId()) { assert f.node().id().equals(nodeId); f.onResult(res); @@ -294,7 +297,7 @@ private boolean rollbackLockTransactions(Collection nodes) { GridDhtTxFinishRequest req = new GridDhtTxFinishRequest( tx.nearNodeId(), futId, - fut.futureId(), + fut.miniId(), tx.topologyVersion(), tx.xidVersion(), tx.commitVersion(), @@ -377,7 +380,7 @@ private boolean finish(Map dhtMap, GridDhtTxFinishRequest req = new GridDhtTxFinishRequest( tx.nearNodeId(), futId, - fut.futureId(), + fut.miniId(), tx.topologyVersion(), tx.xidVersion(), tx.commitVersion(), @@ -432,7 +435,7 @@ private boolean finish(Map dhtMap, GridDhtTxFinishRequest req = new GridDhtTxFinishRequest( tx.nearNodeId(), futId, - fut.futureId(), + fut.miniId(), tx.topologyVersion(), tx.xidVersion(), tx.commitVersion(), @@ -503,7 +506,7 @@ private class MiniFuture extends GridFutureAdapter { private static final long serialVersionUID = 0L; /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** DHT mapping. */ @GridToStringInclude @@ -538,8 +541,8 @@ private MiniFuture(ClusterNode node) { /** * @return Future ID. */ - IgniteUuid futureId() { - return futId; + int miniId() { + return miniId; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java index 2d98e0d0fb88b..0edc153ae8caa 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java @@ -53,7 +53,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest { private TransactionIsolation isolation; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** System invalidation flag. */ private boolean sysInvalidate; @@ -121,7 +121,7 @@ public GridDhtTxFinishRequest() { public GridDhtTxFinishRequest( UUID nearNodeId, IgniteUuid futId, - IgniteUuid miniId, + int miniId, @NotNull AffinityTopologyVersion topVer, GridCacheVersion xidVer, GridCacheVersion commitVer, @@ -160,7 +160,6 @@ public GridDhtTxFinishRequest( txSize, addDepInfo); - assert miniId != null; assert nearNodeId != null; assert isolation != null; @@ -203,7 +202,7 @@ public GridDhtTxFinishRequest( public GridDhtTxFinishRequest( UUID nearNodeId, IgniteUuid futId, - IgniteUuid miniId, + int miniId, @NotNull AffinityTopologyVersion topVer, GridCacheVersion xidVer, GridCacheVersion commitVer, @@ -248,7 +247,7 @@ public GridLongList partUpdateCounters(){ /** * @return Mini ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -378,7 +377,7 @@ public void waitRemoteTransactions(boolean waitRemoteTxs) { writer.incrementState(); case 21: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -476,7 +475,7 @@ public void waitRemoteTransactions(boolean waitRemoteTxs) { reader.incrementState(); case 21: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java index 626ad89bf2502..d4c722d395e79 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java @@ -38,7 +38,7 @@ public class GridDhtTxFinishResponse extends GridDistributedTxFinishResponse { private static final long serialVersionUID = 0L; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** Error. */ @GridDirectTransient @@ -62,18 +62,16 @@ public GridDhtTxFinishResponse() { * @param futId Future ID. * @param miniId Mini future ID. */ - public GridDhtTxFinishResponse(GridCacheVersion xid, IgniteUuid futId, IgniteUuid miniId) { + public GridDhtTxFinishResponse(GridCacheVersion xid, IgniteUuid futId, int miniId) { super(xid, futId); - assert miniId != null; - this.miniId = miniId; } /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -155,7 +153,7 @@ public void checkCommitted(boolean checkCommitted) { writer.incrementState(); case 7: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -193,7 +191,7 @@ public void checkCommitted(boolean checkCommitted) { reader.incrementState(); case 7: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; 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 9ffb52b0e1052..49945219801ff 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 @@ -79,7 +79,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa private IgniteUuid nearFinFutId; /** Near future ID. */ - private IgniteUuid nearFinMiniId; + private int nearFinMiniId; /** Near XID. */ private GridCacheVersion nearXidVer; @@ -253,14 +253,14 @@ public void nearFinishFutureId(IgniteUuid nearFinFutId) { /** * @return Near future mini ID. */ - public IgniteUuid nearFinishMiniId() { + public int nearFinishMiniId() { return nearFinMiniId; } /** * @param nearFinMiniId Near future mini ID. */ - public void nearFinishMiniId(IgniteUuid nearFinMiniId) { + public void nearFinishMiniId(int nearFinMiniId) { this.nearFinMiniId = nearFinMiniId; } 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 078e3225b24ae..e7349e9295433 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 @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; @@ -100,6 +101,8 @@ public final class GridNearTxFinishFuture extends GridCompoundIdentityFutu /** */ private boolean finishOnePhaseCalled; + private final AtomicInteger counter = new AtomicInteger(); + /** * @param cctx Context. * @param tx Transaction. @@ -175,7 +178,7 @@ public void onResult(UUID nodeId, GridNearTxFinishResponse res) { if (fut.getClass() == FinishMiniFuture.class) { FinishMiniFuture f = (FinishMiniFuture)fut; - if (f.futureId().equals(res.miniId())) { + if (f.miniId() == res.miniId()) { assert f.node().id().equals(nodeId); finishFut = f; @@ -201,7 +204,7 @@ public void onResult(UUID nodeId, GridDhtTxFinishResponse res) { if (fut.getClass() == CheckBackupMiniFuture.class) { CheckBackupMiniFuture f = (CheckBackupMiniFuture)fut; - if (f.futureId().equals(res.miniId())) { + if (f.miniId() == res.miniId()) { assert f.node().id().equals(nodeId); f.onDhtFinishResponse(res); @@ -210,7 +213,7 @@ public void onResult(UUID nodeId, GridDhtTxFinishResponse res) { else if (fut.getClass() == CheckRemoteTxMiniFuture.class) { CheckRemoteTxMiniFuture f = (CheckRemoteTxMiniFuture)fut; - if (f.futureId().equals(res.miniId())) + if (f.miniId() == res.miniId()) f.onDhtFinishResponse(nodeId); } } @@ -470,7 +473,7 @@ private void checkBackup() { } } else { - GridDhtTxFinishRequest finishReq = checkCommittedRequest(mini.futureId()); + GridDhtTxFinishRequest finishReq = checkCommittedRequest(mini.miniId()); // Preserve old behavior, otherwise response is not sent. if (WAIT_REMOTE_TXS_SINCE.compareTo(backup.version()) > 0) @@ -599,7 +602,7 @@ private void finish(GridDistributedTxMapping m) { // If this is the primary node for the keys. if (n.isLocal()) { - req.miniId(IgniteUuid.randomUuid()); + req.miniId(counter.incrementAndGet()); IgniteInternalFuture fut = cctx.tm().txHandler().finish(n.id(), tx, req); @@ -610,7 +613,7 @@ private void finish(GridDistributedTxMapping m) { else { FinishMiniFuture fut = new FinishMiniFuture(m); - req.miniId(fut.futureId()); + req.miniId(fut.miniId()); add(fut); // Append new future. @@ -689,7 +692,7 @@ else if (f.getClass() == CheckRemoteTxMiniFuture.class) { * @param miniId Mini future ID. * @return Finish request. */ - private GridDhtTxFinishRequest checkCommittedRequest(IgniteUuid miniId) { + private GridDhtTxFinishRequest checkCommittedRequest(int miniId) { GridDhtTxFinishRequest finishReq = new GridDhtTxFinishRequest( cctx.localNodeId(), futureId(), @@ -725,7 +728,7 @@ private GridDhtTxFinishRequest checkCommittedRequest(IgniteUuid miniId) { */ private abstract class MinFuture extends GridFutureAdapter { /** */ - private final IgniteUuid futId = IgniteUuid.randomUuid(); + private final int miniId = counter.incrementAndGet(); /** * @param nodeId Node ID. @@ -736,8 +739,8 @@ private abstract class MinFuture extends GridFutureAdapter { /** * @return Future ID. */ - final IgniteUuid futureId() { - return futId; + final int miniId() { + return miniId; } } @@ -793,7 +796,7 @@ boolean onNodeLeft(UUID nodeId) { add(mini); - GridDhtTxFinishRequest req = checkCommittedRequest(mini.futureId()); + GridDhtTxFinishRequest req = checkCommittedRequest(mini.miniId()); req.waitRemoteTransactions(true); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java index 65eac63d14c03..3d028f5ced046 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java @@ -39,7 +39,7 @@ public class GridNearTxFinishRequest extends GridDistributedTxFinishRequest { private static final long serialVersionUID = 0L; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** Explicit lock flag. */ private boolean explicitLock; @@ -146,14 +146,14 @@ public boolean storeEnabled() { /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } /** * @param miniId Mini future ID. */ - public void miniId(IgniteUuid miniId) { + public void miniId(int miniId) { this.miniId = miniId; } @@ -200,7 +200,7 @@ public int taskNameHash() { writer.incrementState(); case 19: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -254,7 +254,7 @@ public int taskNameHash() { reader.incrementState(); case 19: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java index b84d2fdc434a8..89023fc49f4e0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java @@ -45,7 +45,7 @@ public class GridNearTxFinishResponse extends GridDistributedTxFinishResponse { private byte[] errBytes; /** Mini future ID. */ - private IgniteUuid miniId; + private int miniId; /** Near tx thread ID. */ private long nearThreadId; @@ -64,12 +64,10 @@ public GridNearTxFinishResponse() { * @param miniId Mini future Id. * @param err Error. */ - public GridNearTxFinishResponse(GridCacheVersion xid, long nearThreadId, IgniteUuid futId, IgniteUuid miniId, + public GridNearTxFinishResponse(GridCacheVersion xid, long nearThreadId, IgniteUuid futId, int miniId, @Nullable Throwable err) { super(xid, futId); - assert miniId != null; - this.nearThreadId = nearThreadId; this.miniId = miniId; this.err = err; @@ -83,7 +81,7 @@ public GridNearTxFinishResponse(GridCacheVersion xid, long nearThreadId, IgniteU /** * @return Mini future ID. */ - public IgniteUuid miniId() { + public int miniId() { return miniId; } @@ -133,7 +131,7 @@ public long threadId() { writer.incrementState(); case 6: - if (!writer.writeIgniteUuid("miniId", miniId)) + if (!writer.writeInt("miniId", miniId)) return false; writer.incrementState(); @@ -169,7 +167,7 @@ public long threadId() { reader.incrementState(); case 6: - miniId = reader.readIgniteUuid("miniId"); + miniId = reader.readInt("miniId"); if (!reader.isLastRead()) return false;