GEODE-8278: Modified initialImagePut to invoke LRU callback methods
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 c29e8c9..9a0d8b6 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
@@ -838,24 +838,23 @@
if (result) {
if (oldIsTombstone) {
owner.unscheduleTombstone(oldRe);
- if (newValue != Token.TOMBSTONE) {
- lruEntryCreate(oldRe);
- } else {
- lruEntryUpdate(oldRe);
- }
}
if (newValue == Token.TOMBSTONE) {
if (!oldIsDestroyedOrRemoved) {
owner.updateSizeOnRemove(key, oldSize);
}
owner.scheduleTombstone(oldRe, entryVersion);
- lruEntryDestroy(oldRe);
+ if (!oldIsTombstone) {
+ lruEntryDestroy(oldRe);
+ }
} else {
int newSize = owner.calculateRegionEntryValueSize(oldRe);
if (!oldIsTombstone) {
owner.updateSizeOnPut(key, oldSize, newSize);
+ lruEntryUpdate(oldRe);
} else {
owner.updateSizeOnCreate(key, newSize);
+ lruEntryCreate(oldRe);
}
EntryLogger.logInitialImagePut(_getOwnerObject(), key, newValue);
}
@@ -943,10 +942,12 @@
done = false;
cleared = true;
} finally {
- if (done && !deferLRUCallback) {
- lruUpdateCallback();
- } else if (!cleared) {
- resetThreadLocals();
+ if (!deferLRUCallback) {
+ if (done) {
+ lruUpdateCallback();
+ } else if (!cleared) {
+ resetThreadLocals();
+ }
}
}
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 70afcc4..47904bf 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
@@ -29,6 +29,7 @@
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -1557,6 +1558,34 @@
assertThat(arm.isInTokenModeNeeded(arm._getOwner(), true)).isTrue();
}
+ @Test
+ public void initialImagePut_lruEntryCreateInvoked() throws RegionClearedException {
+ ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class);
+ RegionEntry entry = mock(RegionEntry.class);
+ when(entry.isTombstone()).thenReturn(true);
+ when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean()))
+ .thenReturn(true);
+ when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry);
+ TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null);
+ TestableAbstractRegionMap armSpy = spy(arm);
+ armSpy.initialImagePut(KEY, 0, "value", true, true, null, null, false);
+ verify(armSpy).lruEntryCreate(entry);
+ }
+
+ @Test
+ public void initialImagePut_lruEntryUpdateInvoked() throws RegionClearedException {
+ ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class);
+ RegionEntry entry = mock(RegionEntry.class);
+ when(entry.isTombstone()).thenReturn(false);
+ when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean()))
+ .thenReturn(true);
+ when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry);
+ TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null);
+ TestableAbstractRegionMap armSpy = spy(arm);
+ armSpy.initialImagePut(KEY, 0, "value", true, true, null, null, false);
+ verify(armSpy).lruEntryUpdate(entry);
+ }
+
private static class TxNoRegionEntryTestableAbstractRegionMap
extends TxTestableAbstractRegionMap {
@Override