RegionVersionVector implements DataSerializableFixedID, MembershipListener { public void recordVersion(T mbr, VersionTag<T> tag) { tag.setRecorded(); assert tag.isRecorded(); T member = tag.getMemberID(); if (member == null) { member = mbr; } if (this.myId.equals(member)) { synchronized (localExceptions) { if (this.localVersion.get() < tag.getRegionVersion() && region != null && region.isInitialized() && region.getDataPolicy().withPersistence()) { Assert.fail( "recordVersion invoked for a local version tag that is higher than our local version. rvv=" + this + ", tag=" + tag + " " + region.getName()); } } } recordVersion(member, tag.getRegionVersion()); } protected  RegionVersionVector(T ownerId, ConcurrentHashMap<T, RegionVersionHolder<T>> vector,
      long version, ConcurrentHashMap<T, Long> gcVersions, long gcVersion, boolean singleMember,
      RegionVersionHolder<T> localExceptions);  RegionVersionVector();  RegionVersionVector(T ownerId);  RegionVersionVector(T ownerId, LocalRegion owner); @VisibleForTesting  RegionVersionVector(T ownerId, LocalRegion owner, long version); RegionVersionVector<T> getCloneForTransmission(); RegionVersionVector<T> getCloneForTransmission(T mbr); Map<T, Long> getTombstoneGCVector(); boolean containsTombstoneGCVersions(Map<T, Long> regionGCVersions); long lockForClear(String regionPath, DistributionManager dm,
      InternalDistributedMember locker); void unlockForClear(InternalDistributedMember locker); long getNextVersion(); long getNextVersionWhileLocked(); void lockForCacheModification(LocalRegion owner); void releaseCacheModificationLock(LocalRegion owner); void lockForCacheModification(); void releaseCacheModificationLock(); long getCurrentVersion(); RegionVersionHolder<T> getLocalExceptions(); RegionVersionHolder<T> getHolderForMember(T id); T getOwnerId(); void turnOffRecordingForEmptyRegion(); void setIsClientVector(); void recordVersions(RegionVersionVector<T> otherVector); void initializeVersionHolder(T mbr, RegionVersionHolder<T> otherHolder); void recordVersion(T mbr, VersionTag<T> tag); void recordVersion(T member, long version); @edu.umd.cs.findbugs.annotations.SuppressWarnings( value = "ML_SYNC_ON_FIELD_TO_GUARD_CHANGING_THAT_FIELD", justification = "sync on localExceptions guards concurrent modification but this is a replacement") void initRecoveredVersion(T member, RegionVersionHolder<T> v, boolean latestOplog); long getVersionForMember(T mbr); Set<T> getDepartedMembersSet(); boolean contains(T id, long version); void removeOldMembers(Set<VersionSource<T>> idsToKeep); boolean containsMember(T id); boolean hasHigherTombstoneGCVersions(RegionVersionVector<T> other); boolean isNewerThanOrCanFillExceptionsFor(RegionVersionVector<T> other); synchronized boolean isRVVGCDominatedBy(RegionVersionVector<T> requesterRVV); boolean waitToDominate(RegionVersionVector<T> otherVector, LocalRegion region); boolean dominates(RegionVersionVector<T> other); void removeExceptionsFor(DistributedMember mbr, long version); void removeOldVersions(); int getExceptionCount(T mbr); T getCanonicalId(T id); @Override void toData(DataOutput out,
      SerializationContext context); @Override void fromData(DataInput in,
      DeserializationContext context); void recordGCVersion(T mbr, long regionVersion); void recordGCVersions(RegionVersionVector<T> other); boolean isTombstoneTooOld(T mbr, long gcVersion); long getGCVersion(T mbr); Map<T, RegionVersionHolder<T>> getMemberToVersion(); synchronized Map<T, Long> getMemberToGCVersion(); void pruneOldExceptions(); @Override String toString(); String fullToString(); @Override void memberJoined(DistributionManager distributionManager, InternalDistributedMember id); @Override void memberSuspect(DistributionManager distributionManager, InternalDistributedMember id,
      InternalDistributedMember whoSuspected, String reason); @Override void quorumLost(DistributionManager distributionManager,
      Set<InternalDistributedMember> failures, List<InternalDistributedMember> remaining); @Override void memberDeparted(DistributionManager distributionManager,
      final InternalDistributedMember id, boolean crashed); static RegionVersionVector<?> create(boolean persistent, DataInput in); static RegionVersionVector<?> create(VersionSource<?> versionMember, LocalRegion owner); boolean sameAs(RegionVersionVector<T> other); boolean logicallySameAs(RegionVersionVector<T> other); boolean isForSynchronization(); boolean isDepartedMember(VersionSource<T> mbr); @Override KnownVersion[] getSerializationVersions(); static final boolean DEBUG; static final long MAX_DOMINANCE_WAIT_TIME; static final long DOMINANCE_PAUSE_TIME; }
@Test public void recordVersionIntoLocalMemberShouldFailIfRegionIsPersistent() { LocalRegion mockRegion = mock(LocalRegion.class); when(mockRegion.isInitialized()).thenReturn(true); when(mockRegion.getDataPolicy()).thenReturn(DataPolicy.PERSISTENT_REPLICATE); final String local = getIPLiteral(); DiskStoreID ownerId = new DiskStoreID(); DiskRegionVersionVector rvv = new DiskRegionVersionVector(ownerId, mockRegion); DiskVersionTag tag = new DiskVersionTag(); tag.setRegionVersion(1L); tag.setMemberID(ownerId); expectedException.expect(InternalGemFireError.class); rvv.recordVersion(ownerId, tag); }