Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 7F774200C61 for ; Mon, 10 Apr 2017 17:55:14 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 7E547160B99; Mon, 10 Apr 2017 15:55:14 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D1158160BB1 for ; Mon, 10 Apr 2017 17:55:10 +0200 (CEST) Received: (qmail 48809 invoked by uid 500); 10 Apr 2017 15:55:10 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 48162 invoked by uid 99); 10 Apr 2017 15:55:09 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 Apr 2017 15:55:09 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 9FE21DFF9F; Mon, 10 Apr 2017 15:55:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: agoncharuk@apache.org To: commits@ignite.apache.org Date: Mon, 10 Apr 2017 15:56:00 -0000 Message-Id: In-Reply-To: <6249ec11a1c540ac927d10c6995c825f@git.apache.org> References: <6249ec11a1c540ac927d10c6995c825f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [53/53] [abbrv] ignite git commit: IGNITE-4851 - Fixed partition destroy race archived-at: Mon, 10 Apr 2017 15:55:15 -0000 IGNITE-4851 - Fixed partition destroy race Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/baa3835e Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/baa3835e Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/baa3835e Branch: refs/heads/ignite-3477-master Commit: baa3835ee60f9c9a0c7229b78c4603504fb5e522 Parents: 54213d6 6e67866 Author: Ilya Lantukh Authored: Mon Apr 10 18:55:00 2017 +0300 Committer: Alexey Goncharuk Committed: Mon Apr 10 18:55:00 2017 +0300 ---------------------------------------------------------------------- .../processors/cache/GridCacheAdapter.java | 2 +- .../cache/GridCacheConcurrentMap.java | 5 +- .../cache/GridCacheConcurrentMapImpl.java | 218 +++++++++++-------- .../cache/GridCacheLocalConcurrentMap.java | 54 +++++ .../processors/cache/GridCacheMapEntry.java | 14 +- .../dht/GridCachePartitionedConcurrentMap.java | 15 +- .../distributed/dht/GridDhtLocalPartition.java | 204 ++++++++++++----- .../distributed/near/GridNearCacheAdapter.java | 3 +- .../cache/GridCacheAbstractFullApiSelfTest.java | 1 + ...ledAtomicOnheapMultiNodeFullApiSelfTest.java | 10 + ...nedAtomicOnheapMultiNodeFullApiSelfTest.java | 10 + .../cache/hibernate/HibernateCacheProxy.java | 2 +- .../cache/hibernate/HibernateCacheProxy.java | 2 +- 13 files changed, 380 insertions(+), 160 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentMapImpl.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentMapImpl.java index 10f5ca3,15a688b..0ef1fdb --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentMapImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentMapImpl.java @@@ -120,103 -116,148 +116,158 @@@ public abstract class GridCacheConcurre GridCacheMapEntry doomed = null; boolean done = false; - + boolean reserved = false; ++ int sizeChange = 0; - while (!done) { - GridCacheMapEntry entry = map.get(key); - created = null; - doomed = null; - - if (entry == null) { - if (create) { - if (created0 == null) - created0 = factory.create(ctx, topVer, key, key.hashCode(), val); + try { + while (!done) { + GridCacheMapEntry entry = map.get(key); + created = null; + doomed = null; - cur = created = created0; + if (entry == null) { + if (create) { + if (created0 == null) { + if (!reserved) { + if (!reserve()) + return null; - done = map.putIfAbsent(created.key(), created) == null; - } - else - done = true; - } - else { - if (entry.obsolete()) { - doomed = entry; + reserved = true; + } - if (create) { - if (created0 == null) created0 = factory.create(ctx, topVer, key, key.hashCode(), val); + } cur = created = created0; - done = map.replace(entry.key(), doomed, created); + done = map.putIfAbsent(created.key(), created) == null; } else - done = map.remove(entry.key(), doomed); + done = true; } else { - cur = entry; + if (entry.obsolete()) { + doomed = entry; + + if (create) { + if (created0 == null) { + if (!reserved) { + if (!reserve()) + return null; + + reserved = true; + } + + created0 = factory.create(ctx, topVer, key, key.hashCode(), val); + } + + cur = created = created0; - done = true; + done = map.replace(entry.key(), doomed, created); + } + else + done = map.remove(entry.key(), doomed); + } + else { + cur = entry; + + done = true; + } } } - } - int sizeChange = 0; - int sizeChange = 0; ++ sizeChange = 0; + + if (doomed != null) { + synchronized (doomed) { + if (!doomed.deleted()) + sizeChange--; + } - if (doomed != null) { - synchronized (doomed) { - if (!doomed.deleted()) - sizeChange--; + if (ctx.events().isRecordable(EVT_CACHE_ENTRY_DESTROYED)) + ctx.events().addEvent(doomed.partition(), + doomed.key(), + ctx.localNodeId(), + (IgniteUuid)null, + null, + EVT_CACHE_ENTRY_DESTROYED, + null, + false, + null, + false, + null, + null, + null, + true); } - if (ctx.events().isRecordable(EVT_CACHE_ENTRY_DESTROYED)) - ctx.events().addEvent(doomed.partition(), - doomed.key(), - ctx.localNodeId(), - (IgniteUuid)null, - null, - EVT_CACHE_ENTRY_DESTROYED, - null, - false, - null, - false, - null, - null, - null, - true); + if (created != null) { + sizeChange++; + + if (ctx.events().isRecordable(EVT_CACHE_ENTRY_CREATED)) + ctx.events().addEvent(created.partition(), + created.key(), + ctx.localNodeId(), + (IgniteUuid)null, + null, + EVT_CACHE_ENTRY_CREATED, + null, + false, + null, + false, + null, + null, + null, + true); + + if (touch) + ctx.evicts().touch( + cur, + topVer); + } + + assert Math.abs(sizeChange) <= 1; + - if (sizeChange == -1) - decrementPublicSize(cur); - else if (sizeChange == 1) { - assert reserved; - - incrementPublicSize(cur); - } - + return cur; } + finally { + if (reserved) - release(); ++ release(sizeChange, cur); ++ else { ++ if (sizeChange != 0) { ++ assert sizeChange == -1; + - if (created != null) { - sizeChange++; - - if (ctx.events().isRecordable(EVT_CACHE_ENTRY_CREATED)) - ctx.events().addEvent(created.partition(), - created.key(), - ctx.localNodeId(), - (IgniteUuid)null, - null, - EVT_CACHE_ENTRY_CREATED, - null, - false, - null, - false, - null, - null, - null, - true); - - if (touch) - ctx.evicts().touch( - cur, - topVer); ++ decrementPublicSize(cur); ++ } ++ } } + } - if (sizeChange != 0) - pubSize.addAndGet(sizeChange); + /** + * + */ + protected boolean reserve() { + return true; + } - return cur; + /** + * + */ + protected void release() { + // No-op. + } + ++ /** ++ * @param sizeChange Size delta. ++ * @param e Map entry. ++ */ ++ protected void release(int sizeChange, GridCacheEntryEx e) { ++ if (sizeChange == 1) ++ incrementPublicSize(e); ++ else if (sizeChange == -1) ++ decrementPublicSize(e); + } + /** {@inheritDoc} */ @Override public boolean removeEntry(final GridCacheEntryEx entry) { boolean removed = map.remove(entry.key(), entry); http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java index 46b2bf8,5c2445a..8566b35 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java @@@ -435,17 -426,21 +426,35 @@@ public class GridDhtLocalPartition exte * Releases previously reserved partition. */ @Override public void release() { ++ release0(0); ++ } ++ ++ @Override protected void release(int sizeChange, GridCacheEntryEx e) { ++ release0(sizeChange); ++ } ++ ++ /** ++ * @param sizeChange Size change delta. ++ */ ++ private void release0(int sizeChange) { while (true) { - long reservations = state.get(); + long state = this.state.get(); - if ((int)(reservations & 0xFFFF) == 0) + int reservations = getReservations(state); + + if (reservations == 0) return; - assert (int)(reservations >> 32) != EVICTED.ordinal(); + assert getPartState(state) != EVICTED; + + long newState = setReservations(state, --reservations); ++ newState = setSize(newState, getSize(newState) + sizeChange); ++ ++ assert getSize(newState) == getSize(state) + sizeChange; // Decrement reservations. - if (state.compareAndSet(reservations, --reservations)) { - if ((reservations & 0xFFFF) == 0 && shouldBeRenting) + if (this.state.compareAndSet(state, newState)) { + if (reservations == 0 && shouldBeRenting) rent(true); try { @@@ -965,6 -963,57 +977,84 @@@ "createTime", U.format(createTime)); } + /** {@inheritDoc} */ + @Override public int publicSize() { + return getSize(state.get()); + } + + /** {@inheritDoc} */ + @Override public void incrementPublicSize(GridCacheEntryEx e) { + while (true) { + long state = this.state.get(); + + if (this.state.compareAndSet(state, setSize(state, getSize(state) + 1))) + return; + } + } + + /** {@inheritDoc} */ + @Override public void decrementPublicSize(GridCacheEntryEx e) { + while (true) { + long state = this.state.get(); + + assert getPartState(state) != EVICTED; + + if (this.state.compareAndSet(state, setSize(state, getSize(state) - 1))) + return; + } + } + ++ /** ++ * @param state Composite state. ++ * @return Partition state. ++ */ + private static GridDhtPartitionState getPartState(long state) { + return GridDhtPartitionState.fromOrdinal((int)(state & (0x0000000000000007L))); + } + ++ /** ++ * @param state Composite state to update. ++ * @param partState Partition state. ++ * @return Updated composite state. ++ */ + private static long setPartState(long state, GridDhtPartitionState partState) { + return (state & (~0x0000000000000007L)) | partState.ordinal(); + } + ++ /** ++ * @param state Composite state. ++ * @return Reservations. ++ */ + private static int getReservations(long state) { + return (int)((state & 0x00000000FFFF0000L) >> 16); + } + ++ /** ++ * @param state Composite state to update. ++ * @param reservations Reservations to set. ++ * @return Updated composite state. ++ */ + private static long setReservations(long state, int reservations) { + return (state & (~0x00000000FFFF0000L)) | (reservations << 16); + } + ++ /** ++ * @param state Composite state. ++ * @return Size. ++ */ + private static int getSize(long state) { + return (int)((state & 0xFFFFFFFF00000000L) >> 32); + } + ++ /** ++ * @param state Composite state to update. ++ * @param size Size to set. ++ * @return Updated composite state. ++ */ + private static long setSize(long state, int size) { + return (state & (~0xFFFFFFFF00000000L)) | ((long)size << 32); + } + /** * Removed entry holder. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java ---------------------------------------------------------------------- diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java index b70ca6a,b70ca6a..af80e00 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java @@@ -400,6 -400,6 +400,7 @@@ public abstract class GridCacheAbstract assertEquals(0, cache.localSize()); assertEquals(0, cache.size()); ++ assertEquals(0, cache.size(ONHEAP)); dfltIgnite = null; } http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCachePartitionedNearDisabledAtomicOnheapMultiNodeFullApiSelfTest.java ---------------------------------------------------------------------- diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCachePartitionedNearDisabledAtomicOnheapMultiNodeFullApiSelfTest.java index 20e7b7a,20e7b7a..eb5a1dd --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCachePartitionedNearDisabledAtomicOnheapMultiNodeFullApiSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCachePartitionedNearDisabledAtomicOnheapMultiNodeFullApiSelfTest.java @@@ -25,4 -25,4 +25,14 @@@ public class GridCachePartitionedNearDi @Override protected CacheAtomicityMode atomicityMode() { return CacheAtomicityMode.ATOMIC; } ++ ++ /** {@inheritDoc} */ ++ @Override protected boolean lockingEnabled() { ++ return false; ++ } ++ ++ /** {@inheritDoc} */ ++ @Override protected boolean txShouldBeUsed() { ++ return false; ++ } } http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedAtomicOnheapMultiNodeFullApiSelfTest.java ---------------------------------------------------------------------- diff --cc modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedAtomicOnheapMultiNodeFullApiSelfTest.java index 703d88c,703d88c..573c5a4 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedAtomicOnheapMultiNodeFullApiSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedAtomicOnheapMultiNodeFullApiSelfTest.java @@@ -25,4 -25,4 +25,14 @@@ public class GridCachePartitionedAtomic @Override protected CacheAtomicityMode atomicityMode() { return CacheAtomicityMode.ATOMIC; } ++ ++ /** {@inheritDoc} */ ++ @Override protected boolean lockingEnabled() { ++ return false; ++ } ++ ++ /** {@inheritDoc} */ ++ @Override protected boolean txShouldBeUsed() { ++ return false; ++ } } http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java ---------------------------------------------------------------------- diff --cc modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java index 69d9097,69d9097..c814f9a --- a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java +++ b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java @@@ -50,7 -50,7 +50,7 @@@ import org.apache.ignite.transactions.T import org.jetbrains.annotations.Nullable; /** -- * Hibernate cache proxy. ++ * Hibernate cache proxy used to substitute hibernate keys with ignite keys. */ public class HibernateCacheProxy implements IgniteInternalCache { /** Delegate. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/baa3835e/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java ---------------------------------------------------------------------- diff --cc modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java index 69d9097,69d9097..c814f9a --- a/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java +++ b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java @@@ -50,7 -50,7 +50,7 @@@ import org.apache.ignite.transactions.T import org.jetbrains.annotations.Nullable; /** -- * Hibernate cache proxy. ++ * Hibernate cache proxy used to substitute hibernate keys with ignite keys. */ public class HibernateCacheProxy implements IgniteInternalCache { /** Delegate. */