public VersionTag getVersionTag() { VersionStamp stamp = regionEntry.getVersionStamp(); if (stamp != null) { return stamp.asVersionTag(); } return null; }
/** * returns a map of keys->versiontags for the test region */ private static Map<String, VersionTag<VersionSource<?>>> getCCRegionVersions() { Map<String, VersionTag<VersionSource<?>>> result = new HashMap<>(); @SuppressWarnings("unchecked") Map<String, Object> regionAsMap = (Map<String, Object>) CCRegion; for (String key : regionAsMap.keySet()) { result.put(key, CCRegion.getRegionEntry(key).getVersionStamp().asVersionTag()); } return result; }
protected StringBuilder appendFieldsToString(final StringBuilder sb) { // OFFHEAP _getValue ok: the current toString on ObjectChunk is safe to use without incing // refcount. sb.append("key=").append(getKey()).append("; rawValue=").append(getValue()); VersionStamp stamp = getVersionStamp(); if (stamp != null) { sb.append("; version=").append(stamp.asVersionTag()).append(";member=") .append(stamp.getMemberID()); } return sb; }
protected HashMap<String, VersionTag> saveVersionTags(LocalRegion region) { HashMap<String, VersionTag> tagmap = new HashMap<String, VersionTag>(); Iterator entryItr = region.entrySet().iterator(); while (entryItr.hasNext()) { RegionEntry entry = ((NonTXEntry) entryItr.next()).getRegionEntry(); String key = (String) entry.getKey(); VersionTag tag = entry.getVersionStamp().asVersionTag(); tagmap.put(key, tag); } return tagmap; }
@Before public void setup() { initMocks(this); VersionStamp versionStamp = mock(VersionStamp.class); when(versionStamp.asVersionTag()).thenReturn(existingVersionTag); when(existingRegionEntry.getVersionStamp()).thenReturn(versionStamp); when(existingRegionEntry.getKey()).thenReturn(key); when(factoryRegionEntry.getKey()).thenReturn(key); when(oldRegionEntry.getKey()).thenReturn(key); when(keyInfo.getKey()).thenReturn(key); when(txId.getMemberId()).thenReturn(myId); }
/** * Test hook - returns the version stamp for an entry in the form of a version tag * * @return the entry version information */ public VersionTag getVersionTag(Object key) { Region.Entry entry = getEntry(key, true); VersionTag tag = null; if (entry != null && entry instanceof EntrySnapshot) { tag = ((EntrySnapshot) entry).getVersionTag(); } else if (entry != null && entry instanceof NonTXEntry) { tag = ((NonTXEntry) entry).getRegionEntry().getVersionStamp().asVersionTag(); } return tag; }
private void scheduleTombstone(RegionEntry entry, VersionTag destroyedVersion, boolean reschedule) { if (destroyedVersion == null) { throw new NullPointerException("destroyed version tag cannot be null"); } if (!reschedule) { incTombstoneCount(1); } if (logger.isTraceEnabled(LogMarker.TOMBSTONE_COUNT_VERBOSE)) { logger.trace(LogMarker.TOMBSTONE_COUNT_VERBOSE, "{} tombstone for {} version={} count is {} entryMap size is {}", reschedule ? "rescheduling" : "scheduling", entry.getKey(), entry.getVersionStamp().asVersionTag(), this.tombstoneCount.get(), this.entries.size()/* , new Exception("stack trace") */); } getGemFireCache().getTombstoneService().scheduleTombstone(this, entry, destroyedVersion); }
@Test public void txApplyDestroy_givenPutIfAbsentReturningNonTombstone_callsUpdateSizeOnRemove() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.getKey()).thenReturn(KEY); when(entry.isTombstone()).thenReturn(false); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(versionStamp.asVersionTag()).thenReturn(mock(VersionTag.class)); when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry).thenReturn(null); TXId txId = mock(TXId.class); when(txId.getMemberId()).thenReturn(mock(InternalDistributedMember.class)); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); arm.txApplyDestroy(KEY, txId, null, false, false, null, null, null, new ArrayList<>(), null, null, false, null, null, 0); verify(arm._getOwner(), times(1)).updateSizeOnRemove(eq(KEY), anyInt()); }
@Test public void txApplyDestroy_givenPutIfAbsentReturningDestroyedOrRemovedEntry_neverCallsUpdateSizeOnRemove() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.isTombstone()).thenReturn(false); when(entry.isDestroyedOrRemoved()).thenReturn(true); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(versionStamp.asVersionTag()).thenReturn(mock(VersionTag.class)); when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry).thenReturn(null); TXId txId = mock(TXId.class); when(txId.getMemberId()).thenReturn(mock(InternalDistributedMember.class)); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); arm.txApplyDestroy(KEY, txId, null, false, false, null, null, null, new ArrayList<>(), null, null, false, null, null, 0); verify(arm._getOwner(), never()).updateSizeOnRemove(any(), anyInt()); }
@Test public void initialImagePut_givenPutIfAbsentReturningDestroyedOrRemovedEntry_neverCallsUpdateSizeOnRemove() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.isDestroyedOrRemoved()).thenReturn(true); when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean())) .thenReturn(true); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(versionStamp.asVersionTag()).thenReturn(mock(VersionTag.class)); when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry).thenReturn(null); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); when(arm._getOwner().getServerProxy()).thenReturn(mock(ServerRegionProxy.class)); VersionTag versionTag = mock(VersionTag.class); when(versionTag.getMemberID()).thenReturn(mock(VersionSource.class)); arm.initialImagePut(KEY, 0, Token.TOMBSTONE, false, false, versionTag, null, false); verify(arm._getOwner(), never()).updateSizeOnRemove(any(), anyInt()); }
@Test public void initialImagePut_givenPutIfAbsentReturningNonTombstone_callsUpdateSizeOnRemove() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.isTombstone()).thenReturn(false); when(entry.isDestroyedOrRemoved()).thenReturn(false); when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean())) .thenReturn(true); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(versionStamp.asVersionTag()).thenReturn(mock(VersionTag.class)); when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry).thenReturn(null); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, null); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); when(arm._getOwner().getServerProxy()).thenReturn(mock(ServerRegionProxy.class)); VersionTag versionTag = mock(VersionTag.class); when(versionTag.getMemberID()).thenReturn(mock(VersionSource.class)); arm.initialImagePut(KEY, 0, Token.TOMBSTONE, false, false, versionTag, null, false); verify(arm._getOwner(), times(1)).updateSizeOnRemove(eq(KEY), anyInt()); }
@Test public void initialImagePut_givenPutIfAbsentReturningRegionEntryOldIsTombstone_callUnscheduleTombstone() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.isTombstone()).thenReturn(true); when(entry.isDestroyedOrRemoved()).thenReturn(false); when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean())) .thenReturn(true); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(versionStamp.asVersionTag()).thenReturn(mock(VersionTag.class)); RegionEntry createdEntry = mock(RegionEntry.class); when(createdEntry.getVersionStamp()).thenReturn(versionStamp); when(createdEntry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean())) .thenReturn(true); RegionEntryFactory factory = mock(RegionEntryFactory.class); when(factory.createEntry(any(), any(), any())).thenReturn(createdEntry); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, factory); when(map.putIfAbsent(eq(KEY), any())).thenReturn(entry); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); when(arm._getOwner().getServerProxy()).thenReturn(mock(ServerRegionProxy.class)); VersionTag versionTag = mock(VersionTag.class); when(versionTag.getMemberID()).thenReturn(mock(VersionSource.class)); arm.initialImagePut(KEY, 0, Token.TOMBSTONE, false, false, versionTag, null, false); verify(arm._getOwner(), times(1)).unscheduleTombstone(entry); }
@Test public void initialImagePut_givenPutIfAbsentReturningRegionEntryAndSameTombstoneWillAttemptToRemoveREAndInvokeNothingElse() throws RegionClearedException { ConcurrentMapWithReusableEntries map = mock(ConcurrentMapWithReusableEntries.class); RegionEntry entry = mock(RegionEntry.class); when(entry.isTombstone()).thenReturn(false); when(entry.isDestroyedOrRemoved()).thenReturn(false); when(entry.initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean())) .thenReturn(true); VersionStamp versionStamp = mock(VersionStamp.class); when(entry.getVersionStamp()).thenReturn(versionStamp); when(entry.isTombstone()).thenReturn(true); TestableVersionTag versionTag = new TestableVersionTag(); versionTag.setVersionSource(mock(VersionSource.class)); when(versionStamp.asVersionTag()).thenReturn(versionTag); RegionEntry createdEntry = mock(RegionEntry.class); when(createdEntry.getVersionStamp()).thenReturn(versionStamp); RegionEntryFactory factory = mock(RegionEntryFactory.class); when(factory.createEntry(any(), any(), any())).thenReturn(createdEntry); TestableAbstractRegionMap arm = new TestableAbstractRegionMap(false, map, factory); when(map.putIfAbsent(eq(KEY), eq(createdEntry))).thenReturn(entry); when(arm._getOwner().getConcurrencyChecksEnabled()).thenReturn(true); when(arm._getOwner().getServerProxy()).thenReturn(mock(ServerRegionProxy.class)); arm.initialImagePut(KEY, 0, Token.TOMBSTONE, false, false, versionTag, null, false); verify(map, times(1)).remove(eq(KEY), eq(createdEntry)); verify(entry, never()).initialImagePut(any(), anyLong(), any(), anyBoolean(), anyBoolean()); }
/** * Create one of these in the local case so that we have a snapshot of the state and can allow the * bucket to move out from under us. */ public NonLocalRegionEntry(RegionEntry re, InternalRegion br, boolean allowTombstones) { this.key = re.getKey(); if (allowTombstones && re.isTombstone()) { // client get() operations need to see tombstone values this.value = Token.TOMBSTONE; } else { this.value = re.getValue(br); // OFFHEAP: copy into heap cd } Assert.assertTrue(this.value != Token.NOT_AVAILABLE, "getEntry did not fault value in from disk"); this.lastModified = re.getLastModified(); this.isRemoved = re.isRemoved(); VersionStamp stamp = re.getVersionStamp(); if (stamp != null) { this.versionTag = stamp.asVersionTag(); } }
@Override protected boolean operateOnRegion(ClusterDistributionManager dm, LocalRegion r, long startTime) throws RemoteOperationException { r.waitOnInitialization(); VersionTag<?> tag; try { RegionEntry re = r.getRegionEntry(key); if (re == null) { if (logger.isTraceEnabled(LogMarker.DM_VERBOSE)) { logger.trace(LogMarker.DM_VERBOSE, "RemoteFetchVersionMessage did not find entry for key:{}", key); } r.checkEntryNotFound(key); } tag = re.getVersionStamp().asVersionTag(); if (logger.isTraceEnabled(LogMarker.DM_VERBOSE)) { logger.trace("RemoteFetchVersionMessage for key:{} returning tag:{}", key, tag); } FetchVersionReplyMessage.send(getSender(), processorId, tag, dm); } catch (EntryNotFoundException e) { sendReply(getSender(), getProcessorId(), dm, new ReplyException(e), r, startTime); } return false; }
@Test public void testClientEventIsUpdatedWithCurrentEntryVersionTagAfterSearchConcurrencyException() { DistributedRegion region = prepare(true); EntryEventImpl event = createDummyEvent(region); region.basicInvalidate(event); VersionTag tag = createVersionTag(true); RegionEntry re = mock(RegionEntry.class); VersionStamp stamp = mock(VersionStamp.class); doReturn(re).when(region).getRegionEntry(any()); when(re.getVersionStamp()).thenReturn(stamp); when(stamp.asVersionTag()).thenReturn(tag); createSearchLoad(); doThrow(new ConcurrentCacheModificationException()).when(region) .basicPutEntry(any(EntryEventImpl.class), anyLong()); KeyInfo ki = new KeyInfo(event.getKey(), null, null); region.findObjectInSystem(ki, false, null, false, null, false, false, null, event, false); assertNotNull("ClientEvent version tag is not set with region version tag.", event.getVersionTag()); }
private void copyRecoveredEntry(RegionEntry oldRe, RegionEntry newRe) { if (newRe.getVersionStamp() != null) { newRe.getVersionStamp().setMemberID(oldRe.getVersionStamp().getMemberID()); newRe.getVersionStamp().setVersions(oldRe.getVersionStamp().asVersionTag()); } if (newRe instanceof AbstractOplogDiskRegionEntry) { ((AbstractOplogDiskRegionEntry) newRe).setDiskId(oldRe); _getOwner().getDiskRegion().replaceIncompatibleEntry((DiskEntry) oldRe, (DiskEntry) newRe); } getEntryMap().put(newRe.getKey(), newRe); }
private void updateEventWithCurrentRegionEntry(EntryEventImpl event, EntryEventImpl clientEvent) { // defer the lruUpdateCallback to prevent a deadlock (see bug 51121). final boolean disabled = this.entries.disableLruUpdateCallback(); try { RegionEntry re = getRegionEntry(event.getKey()); if (re != null) { synchronized (re) { // bug #51059 value & version must be obtained atomically // Update client event with latest version tag from re if (clientEvent != null) { clientEvent.setVersionTag(re.getVersionStamp().asVersionTag()); } // OFFHEAP: need to incrc, copy to heap to setNewValue, decrc event.setNewValue(re.getValue(this)); } } } finally { if (disabled) { this.entries.enableLruUpdateCallback(); } try { this.entries.lruUpdateCallback(); } catch (DiskAccessException dae) { this.handleDiskAccessException(dae); throw dae; } } }
@Test public void stampWithoutDSIDShouldAcceptAnyTag() { GemFireCacheImpl cache = mock(GemFireCacheImpl.class); LocalRegion lr = mock(LocalRegion.class); String value = "value"; AbstractRegionEntry re = new TestableRegionEntry(lr, value); InternalDistributedMember member1 = mock(InternalDistributedMember.class); EntryEventImpl entryEvent1 = new EntryEventImpl(); entryEvent1.setRegion(lr); when(lr.getCache()).thenReturn(cache); when(cache.getGatewayConflictResolver()).thenReturn(null); VersionTag tag1 = VersionTag.create(member1); tag1.setVersionTimeStamp(1); tag1.setDistributedSystemId(-1); tag1.setIsGatewayTag(true); VersionTag tag2 = VersionTag.create(member1); tag2.setVersionTimeStamp(2); tag2.setDistributedSystemId(2); tag2.setIsGatewayTag(true); ((TestableRegionEntry) re).setVersions(tag1); assertEquals(tag1.getVersionTimeStamp(), re.getVersionStamp().asVersionTag().getVersionTimeStamp()); assertEquals(-1, ((TestableRegionEntry) re).getDistributedSystemId()); // apply tag2 should be accepted entryEvent1.setVersionTag(tag2); re.processVersionTag(entryEvent1); }
private boolean checkUpdatePreconditions() { if (isIfOld()) { final EntryEventImpl event = getEvent(); final RegionEntry re = getRegionEntry(); // only update, so just do tombstone maintainence and exit if (re.isTombstone() && event.getVersionTag() != null) { // refresh the tombstone so it doesn't time out too soon getRegionMap().processVersionTag(re, event); try { re.setValue(getOwner(), Token.TOMBSTONE); } catch (RegionClearedException e) { // that's okay - when writing a tombstone into a disk, the // region has been cleared (including this tombstone) } getOwner().rescheduleTombstone(re, re.getVersionStamp().asVersionTag()); return false; } if (re.isRemoved() && !isReplaceOnClient()) { return false; } } return true; }