GEODE-3204: txApplyInvalidate in AbstractRegionMap on farside does not update 
on a region entry with removed token.


Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/0bce1eaf
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/0bce1eaf
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/0bce1eaf

Branch: refs/heads/feature/GEM-1483
Commit: 0bce1eaffd1b8c0f482519ec47ea43231e8f40f1
Parents: a1ee957
Author: eshu <e...@pivotal.io>
Authored: Mon Jul 17 09:14:36 2017 -0700
Committer: eshu <e...@pivotal.io>
Committed: Mon Jul 17 09:14:36 2017 -0700

----------------------------------------------------------------------
 .../geode/internal/cache/AbstractRegionMap.java | 13 +++---
 .../internal/cache/AbstractRegionMapTest.java   | 48 ++++++++++++++++++++
 2 files changed, 54 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/0bce1eaf/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
index 7f12eab..f958f94 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/AbstractRegionMap.java
@@ -2513,9 +2513,9 @@ public abstract class AbstractRegionMap implements 
RegionMap {
         RegionEntry re = getEntry(key);
         if (re != null) {
           synchronized (re) {
-            {
+            // Fix GEODE-3204, do not invalidate the region entry if it is a 
removed token
+            if (!Token.isRemoved(re.getValueAsToken())) {
               final int oldSize = owner.calculateRegionEntryValueSize(re);
-              boolean wasTombstone = re.isTombstone();
               Object oldValue = re.getValueInVM(owner); // OFFHEAP eei
               // Create an entry event only if the calling context is
               // a receipt of a TXCommitMessage AND there are callbacks
@@ -2543,9 +2543,6 @@ public abstract class AbstractRegionMap implements 
RegionMap {
                 try {
                   re.setValue(owner, re.prepareValueForCache(owner, newValue, 
true));
                   EntryLogger.logTXInvalidate(_getOwnerObject(), key);
-                  if (wasTombstone) {
-                    owner.unscheduleTombstone(re);
-                  }
                   owner.updateSizeOnPut(key, oldSize, 0);
                 } catch (RegionClearedException rce) {
                   clearOccured = true;
@@ -2572,9 +2569,11 @@ public abstract class AbstractRegionMap implements 
RegionMap {
                 if (!cbEventInPending)
                   cbEvent.release();
               }
+              return;
             }
           }
-        } else { // re == null
+        }
+        { // re == null or region entry is removed token.
           // Fix bug#43594
           // In cases where bucket region is re-created, it may so happen
           // that the invalidate is already applied on the Initial image
@@ -3107,7 +3106,7 @@ public abstract class AbstractRegionMap implements 
RegionMap {
 
     final boolean hasRemoteOrigin = !((TXId) 
txId).getMemberId().equals(owner.getMyId());
     final boolean isTXHost = txEntryState != null;
-    final boolean isClientTXOriginator = owner.cache.isClient() && 
!hasRemoteOrigin;
+    final boolean isClientTXOriginator = owner.getCache().isClient() && 
!hasRemoteOrigin;
     final boolean isRegionReady = owner.isInitialized();
     @Released
     EntryEventImpl cbEvent = null;

http://git-wip-us.apache.org/repos/asf/geode/blob/0bce1eaf/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractRegionMapTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractRegionMapTest.java
 
b/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractRegionMapTest.java
index 60b93a9..893d842 100644
--- 
a/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractRegionMapTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/cache/AbstractRegionMapTest.java
@@ -15,7 +15,9 @@
 package org.apache.geode.internal.cache;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
@@ -31,6 +33,7 @@ import static org.mockito.Mockito.when;
 import org.apache.geode.cache.DataPolicy;
 import org.apache.geode.cache.EntryNotFoundException;
 import org.apache.geode.cache.Operation;
+import 
org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.cache.versions.VersionHolder;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.junit.Test;
@@ -187,4 +190,49 @@ public class AbstractRegionMapTest {
       initialize(owner, new Attributes(), null, false);
     }
   }
+
+  private static class TxTestableAbstractRegionMap extends AbstractRegionMap {
+
+    public LocalRegion owner;
+
+    protected TxTestableAbstractRegionMap() {
+      super(null);
+      this.owner = mock(LocalRegion.class);
+      when(this.owner.getCache()).thenReturn(mock(InternalCache.class));
+      when(this.owner.isAllEvents()).thenReturn(true);
+      when(this.owner.isInitialized()).thenReturn(true);
+      initialize(owner, new Attributes(), null, false);
+    }
+  }
+
+  @Test
+  public void txApplyInvalidateDoesNotInvalidateRemovedToken() throws 
RegionClearedException {
+    TxTestableAbstractRegionMap arm = new TxTestableAbstractRegionMap();
+
+    Object key = "key";
+    Object newValue = "value";
+    arm.txApplyPut(Operation.CREATE, key, newValue, false,
+        new TXId(mock(InternalDistributedMember.class), 1), 
mock(TXRmtEvent.class),
+        mock(EventID.class), null, null, null, null, null, null, 1);
+    RegionEntry re = arm.getEntry(key);
+    assertNotNull(re);
+
+    Token[] removedTokens =
+        {Token.REMOVED_PHASE2, Token.REMOVED_PHASE1, Token.DESTROYED, 
Token.TOMBSTONE};
+
+    for (Token token : removedTokens) {
+      verifyTxApplyInvalidate(arm, key, re, token);
+    }
+
+  }
+
+  private void verifyTxApplyInvalidate(TxTestableAbstractRegionMap arm, Object 
key, RegionEntry re,
+      Token token) throws RegionClearedException {
+    re.setValue(arm.owner, token);
+    arm.txApplyInvalidate(key, Token.INVALID, false,
+        new TXId(mock(InternalDistributedMember.class), 1), 
mock(TXRmtEvent.class), false,
+        mock(EventID.class), null, null, null, null, null, null, 1);
+    assertEquals(re.getValueAsToken(), token);
+  }
+
 }

Reply via email to