ignite-2545 Optimization for GridCompoundFuture's futures iteration
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5c5d70bc Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5c5d70bc Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5c5d70bc Branch: refs/heads/ignite-4371 Commit: 5c5d70bcbc9f7bd44cdb3578ddc3bab9b6894956 Parents: e7d0445 Author: sboikov <[email protected]> Authored: Wed Dec 7 12:25:32 2016 +0300 Committer: devozerov <[email protected]> Committed: Thu Dec 15 12:47:28 2016 +0300 ---------------------------------------------------------------------- .../distributed/GridCacheTxRecoveryFuture.java | 4 +- .../cache/distributed/dht/GridDhtGetFuture.java | 2 +- .../distributed/dht/GridDhtLockFuture.java | 4 +- .../distributed/dht/GridDhtTxPrepareFuture.java | 4 +- .../colocated/GridDhtColocatedLockFuture.java | 4 +- .../distributed/near/GridNearLockFuture.java | 4 +- ...arOptimisticSerializableTxPrepareFuture.java | 4 +- .../near/GridNearOptimisticTxPrepareFuture.java | 15 ++++-- .../GridNearPessimisticTxPrepareFuture.java | 4 +- .../near/GridNearTxFinishFuture.java | 4 +- .../util/future/GridCompoundFuture.java | 56 +++++++++++++------- 11 files changed, 74 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java index c07a817..e27f777 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java @@ -427,8 +427,10 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<Boolean> fut = future(i); if (!isMini(fut)) http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java index d2a3b3c..d2eab5f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java @@ -275,7 +275,7 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col // Optimization to avoid going through compound future, // if getAsync() has been completed and no other futures added to this // compound future. - if (fut.isDone() && futuresCount() == 0) { + if (fut.isDone() && !hasFutures()) { if (fut.error() != null) onDone(fut.error()); else http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java index dd18d7a..3f35305 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 @@ -526,8 +526,10 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean> private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { MiniFuture mini = (MiniFuture) future(i); if (mini.futureId().equals(miniId)) { http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java index 8aeecf8..ca2b494 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 @@ -565,8 +565,10 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<IgniteInternalTx> fut = future(i); if (!isMini(fut)) http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java index 959ffa3..742f004 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 @@ -482,8 +482,10 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<Boolean> fut = future(i); if (!isMini(fut)) http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java index f1682b7..96de08b 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 @@ -529,8 +529,10 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<Boolean> fut = future(i); if (!isMini(fut)) http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java index 3676a3c..c464b36 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 @@ -230,8 +230,10 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i); if (!isMini(fut)) http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java index 87c9e1d..b314b81 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java @@ -202,7 +202,9 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa @SuppressWarnings("ForLoopReplaceableByForEach") public Set<IgniteTxKey> requestedKeys() { synchronized (sync) { - for (int i = 0; i < futuresCount(); i++) { + int size = futuresCountNoLock(); + + for (int i = 0; i < size; i++) { IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i); if (isMini(fut) && !fut.isDone()) { @@ -233,8 +235,10 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = size - 1; i >= 0; i--) { IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i); if (!isMini(fut)) @@ -687,7 +691,9 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa keys = new HashSet<>(keyLockFut.lockKeys); else { synchronized (sync) { - for (int i = 0; i < futuresCount(); i++) { + int size = futuresCountNoLock(); + + for (int i = 0; i < size; i++) { IgniteInternalFuture<GridNearTxPrepareResponse> fut = future(i); if (isMini(fut) && !fut.isDone()) { @@ -895,7 +901,8 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa } else remap(); - } else { + } + else { parent.onPrepareResponse(m, res); // Proceed prepare before finishing mini future. http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java index 01fb5fd..f9a2f90 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java @@ -133,8 +133,10 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA private MiniFuture miniFuture(IgniteUuid miniId) { // We iterate directly over the futs collection here to avoid copy. synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { MiniFuture mini = (MiniFuture) future(i); if (mini.futureId().equals(miniId)) { http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java index f14d747..54bd543 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 @@ -201,7 +201,9 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu FinishMiniFuture finishFut = null; synchronized (sync) { - for (int i = 0; i < futuresCount(); i++) { + int size = futuresCountNoLock(); + + for (int i = 0; i < size; i++) { IgniteInternalFuture<IgniteInternalTx> fut = future(i); if (fut.getClass() == FinishMiniFuture.class) { http://git-wip-us.apache.org/repos/asf/ignite/blob/5c5d70bc/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java index 0f7e020..7abd367 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java @@ -88,7 +88,7 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig } /** {@inheritDoc} */ - @Override public void apply(IgniteInternalFuture<T> fut) { + @Override public final void apply(IgniteInternalFuture<T> fut) { try { T t = fut.get(); @@ -160,9 +160,9 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @return Collection of futures. */ @SuppressWarnings("unchecked") - public Collection<IgniteInternalFuture<T>> futures() { + public final Collection<IgniteInternalFuture<T>> futures() { synchronized (sync) { - if(futs == null) + if (futs == null) return Collections.emptyList(); if (futs instanceof IgniteInternalFuture) @@ -190,10 +190,12 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @return {@code True} if there are pending futures. */ @SuppressWarnings("ForLoopReplaceableByForEach") - public boolean hasPending() { + protected final boolean hasPending() { synchronized (sync) { + int size = futuresCountNoLock(); + // Avoid iterator creation and collection copy. - for (int i = 0; i < futuresCount(); i++) { + for (int i = 0; i < size; i++) { IgniteInternalFuture<T> fut = future(i); if (!fut.isDone()) @@ -210,7 +212,7 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @param fut Future to add. */ @SuppressWarnings("unchecked") - public void add(IgniteInternalFuture<T> fut) { + public final void add(IgniteInternalFuture<T> fut) { assert fut != null; synchronized (sync) { @@ -243,7 +245,7 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig /** * Clear futures. */ - protected void clear() { + protected final void clear() { synchronized (sync) { futs = null; } @@ -253,14 +255,14 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @return {@code True} if this future was initialized. Initialization happens when {@link #markInitialized()} * method is called on future. */ - public boolean initialized() { + public final boolean initialized() { return initFlag == INIT_FLAG; } /** * Mark this future as initialized. */ - public void markInitialized() { + public final void markInitialized() { if (FLAGS_UPD.compareAndSet(this, 0, INIT_FLAG)) checkComplete(); } @@ -295,9 +297,9 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @return Future. */ @SuppressWarnings("unchecked") - protected IgniteInternalFuture<T> future(int idx) { + protected final IgniteInternalFuture<T> future(int idx) { assert Thread.holdsLock(sync); - assert futs != null && idx >= 0 && idx < futuresCount(); + assert futs != null && idx >= 0 && idx < futuresCountNoLock(); if (futs instanceof IgniteInternalFuture) { assert idx == 0; @@ -312,15 +314,33 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> implements Ig * @return Futures size. */ @SuppressWarnings("unchecked") - protected int futuresCount() { - synchronized (sync) { - if (futs == null) - return 0; + protected final int futuresCountNoLock() { + assert Thread.holdsLock(sync); - if (futs instanceof IgniteInternalFuture) - return 1; + if (futs == null) + return 0; + + if (futs instanceof IgniteInternalFuture) + return 1; - return ((Collection<IgniteInternalFuture>)futs).size(); + return ((Collection<IgniteInternalFuture>)futs).size(); + } + + /** + * @return Futures size. + */ + private int futuresCount() { + synchronized (sync) { + return futuresCountNoLock(); + } + } + + /** + * @return {@code True} if has at least one future. + */ + protected final boolean hasFutures() { + synchronized (sync) { + return futs != null; } }
