You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/04/12 07:33:53 UTC
[22/57] [abbrv] ignite git commit: IGNITE-4851 - Fixed partition
destroy race
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-debug
Commit: baa3835ee60f9c9a0c7229b78c4603504fb5e522
Parents: 54213d6 6e67866
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Mon Apr 10 18:55:00 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
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<Object, Object> {
/** 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<Object, Object> {
/** Delegate. */