@VisibleForTesting RegionVersionVector(T ownerId, LocalRegion owner, long version) { this.myId = ownerId; this.isLiveVector = true; this.region = owner; this.localExceptions = new RegionVersionHolder<T>(0); this.memberToVersion = new ConcurrentHashMap<>(INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL); this.memberToGCVersion = new ConcurrentHashMap<>(INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL); this.localVersion.set(version); }
private void recordVersionWithoutBitSet(long version) { if ((version - this.version) > 1) { this.addException(this.version, version); logRecordVersion(version); this.version = version; return; } if (this.version > version) { this.addOlderVersion(version); } this.version = Math.max(this.version, version); }
if (source == null || getVersion() > source.getVersion()) { return true; RegionVersionHolder<T> other = source.clone(); mergeBitSet(); // dump the bit-set exceptions into the regular exceptions list other.mergeBitSet(); List<RVVException> mine = canonicalExceptions(this.exceptions); Iterator<RVVException> myIterator = mine.iterator(); List<RVVException> others = canonicalExceptions(other.exceptions); Iterator<RVVException> otherIterator = others.iterator(); || isSpecialException(otherException, other)) { otherException = otherIterator.hasNext() ? otherIterator.next() : null; return true; if (isSpecialException(myException, this)) { if (isSpecialException(otherException, other)) {
public synchronized int hashCode() { mergeBitSet(); final int prime = 31; int result = 1; result = prime * result + (int) version; result = prime * result + (int) (version >> 32); result = prime * result + canonicalExceptions(exceptions).hashCode(); return result; }
private boolean isGCVersionDominatedByOtherHolder(Long gcVersion, RegionVersionHolder<T> otherHolder) { if (gcVersion == null || gcVersion.longValue() == 0) { return true; } else { RegionVersionHolder<T> holder = new RegionVersionHolder<T>(gcVersion.longValue()); return !holder.isNewerThanOrCanFillExceptionsFor(otherHolder); } }
@Test public void test48066_1() { RegionVersionHolder vh1 = new RegionVersionHolder(member); for (int i = 1; i <= 3; i++) { vh1.recordVersion(i); } System.out.println("vh1=" + vh1); RegionVersionHolder vh2 = vh1.clone(); System.out.println("after clone, vh2=" + vh2); { RegionVersionHolder vh3 = new RegionVersionHolder(member); for (int i = 1; i <= 10; i++) { vh3.recordVersion(i); } // create special exception 10(3-11), bitsetVerson=3 vh3.initializeFrom(vh2); System.out.println("after init, vh3=" + vh3); assertEquals(3, vh3.getVersion()); // to make bsv3,bs=[0,1] vh3.recordVersion(4); System.out.println("after record 4, vh3="); assertEquals(4, vh3.getVersion()); vh3.recordVersion(7); System.out.println("after record 7, vh3=" + vh3); assertEquals(7, vh3.getVersion()); } }
private void fillException(boolean useBitSet) { RegionVersionHolder h = createHolder(useBitSet); h.recordVersion(3l); h.recordVersion(1l); h.recordVersion(2l); h.recordVersion(2l); assertEquals(0, h.getExceptionCount()); assertEquals(3l, h.getVersion()); }
RegionVersionHolder vh2 = new RegionVersionHolder(member); vh2.initializeFrom(vh1); assertEquals("RVV=" + vh2, 100, vh2.getVersion()); vh2.initializeFrom(vh1); assertEquals(100, vh2.getVersion()); compareWithBitSet(bs1, vh2); RegionVersionHolder vh4 = vh2.clone(); assertEquals(105, vh4.version); assertEquals(100, vh4.getVersion()); compareWithBitSet(bs1, vh4); vh1.addException(100, 106); assertTrue(vh2.sameAs(vh1)); validateExceptions(vh2);
mergeBitSet(); if (getVersion() != other.getVersion()) { return false; RegionVersionHolder<T> vh1 = this.clone(); RegionVersionHolder<T> vh2 = other.clone(); vh1.removeSpecialException(); vh2.removeSpecialException(); if (vh1.exceptions == null || vh1.exceptions.isEmpty()) { if (vh2.exceptions != null && !vh2.exceptions.isEmpty()) { List<RVVException> e1 = canonicalExceptions(vh1.exceptions); List<RVVException> e2 = canonicalExceptions(vh2.exceptions); Iterator<RVVException> it1 = e1.iterator(); Iterator<RVVException> it2 = e2.iterator();
@Test public void isRvvGcDominatedByRequesterRvvReturnsTrueIfRequesterRvvForLostMemberDominates() throws Exception { InternalDistributedMember lostMember = mock(InternalDistributedMember.class); ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = new ConcurrentHashMap<>(); memberToGcVersion.put(lostMember, new Long(1) /* lostMemberGcVersion */); RegionVersionVector providerRvv = new VMRegionVersionVector(lostMember, null, 0, memberToGcVersion, 0, true, null); ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = new ConcurrentHashMap<>(); RegionVersionHolder regionVersionHolder = new RegionVersionHolder(lostMember); regionVersionHolder.setVersion(2); memberToRegionVersionHolder.put(lostMember, regionVersionHolder); RegionVersionVector requesterRvv = new VMRegionVersionVector(lostMember, memberToRegionVersionHolder, 0, null, 0, true, null); assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isTrue(); }
@Test public void testFillSpecialExceptionWithBitSet() { RegionVersionHolder h = createHolder(true); h.recordVersion(1l); createSpecialException(h); assertEquals(1, h.getExceptionCount()); RVVException e = (RVVException) h.getExceptionForTest().iterator().next(); assertTrue(h.isSpecialException(e, h)); h.recordVersion(2l); // BUG: the exception is not removed // assertIndexDetailsEquals("unexpected RVV exception : " + h, 0, h.getExceptionCount()); }
public void initializeVersionHolder(T mbr, RegionVersionHolder<T> otherHolder) { RegionVersionHolder<T> h = this.memberToVersion.get(mbr); if (h == null) { if (!mbr.equals(this.myId)) { h = otherHolder.clone(); h.makeReadyForRecording(); this.memberToVersion.put(mbr, h); } else { RegionVersionHolder<T> vh = otherHolder; long version = vh.version; updateLocalVersion(version); this.localExceptions.initializeFrom(vh); } } else { // holders must be modified under synchronization h.initializeFrom(otherHolder); } }
RegionVersionHolder vh1 = new RegionVersionHolder(member()); RegionVersionHolder vh2 = new RegionVersionHolder(member()); assertEquals("vector is incorrect on item " + i, !exceptions.contains(i), vh1.contains(i)); vh2.initializeFrom(vh1); assertEquals("vector is incorrect on item " + i, !exceptions.contains(i), vh2.contains(i));
RegionVersionHolder vh1 = new RegionVersionHolder(member); RegionVersionHolder vh2 = new RegionVersionHolder(member); vh1.recordVersion(100); BitSet bs1 = new BitSet(); bs1.set(1, 100); bs2.set(1, 105); recordVersions(vh2, bs2); assertFalse(vh1.dominates(vh2)); assertTrue(vh2.dominates(vh1)); RegionVersionHolder vh1 = new RegionVersionHolder(member); RegionVersionHolder vh2 = new RegionVersionHolder(member); vh1.recordVersion(2 * originalBitSetWidth); assertFalse(vh1.dominates(vh2)); assertTrue(vh2.dominates(vh1)); RegionVersionHolder vh1 = new RegionVersionHolder(member); RegionVersionHolder vh2 = new RegionVersionHolder(member); BitSet bs1 = new BitSet(); bs1.set(1, 21); assertFalse(vh1.dominates(vh2)); assertFalse(vh2.dominates(vh1)); RegionVersionHolder vh1 = new RegionVersionHolder(member);
/** * Retrieve a vector that can be sent to another member. This clones only the version information * for the given ID. * <p> * The clone returned by this method does not have distributed garbage-collection information. */ public RegionVersionVector<T> getCloneForTransmission(T mbr) { Map<T, RegionVersionHolder<T>> liveHolders; liveHolders = new HashMap<T, RegionVersionHolder<T>>(this.memberToVersion); RegionVersionHolder<T> holder = liveHolders.get(mbr); if (holder == null) { holder = new RegionVersionHolder<T>(-1); } else { holder = holder.clone(); } return createCopy(this.myId, new ConcurrentHashMap<T, RegionVersionHolder<T>>(Collections.singletonMap(mbr, holder)), 0, new ConcurrentHashMap<T, Long>(INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL), 0, true, new RegionVersionHolder<T>(-1)); }
private void createSpecialException(RegionVersionHolder h) { h.addException(h.getVersion() - 1, h.getVersion() + 1); }
justification = "sync on localExceptions guards concurrent modification but this is a replacement") public void initRecoveredVersion(T member, RegionVersionHolder<T> v, boolean latestOplog) { RegionVersionHolder<T> recovered = v.clone(); recovered.removeExceptionsOlderThan(gcVersion);
if (holder == null) { mbr = getCanonicalId(mbr); holder = new RegionVersionHolder<T>(mbr); memberToVersion.put(holder.id, holder); logger.trace(LogMarker.RVV_VERBOSE, "Recording rv{} for {}", version, mbr); holder.recordVersion(version);
/** * return the current version for this member */ public long getCurrentVersion() { synchronized (localExceptions) { syncLocalVersion(); return localExceptions.getVersion(); } }
public synchronized long getVersion() { RVVException e = null; List<RVVException> exs = getExceptions(); if (!exs.isEmpty()) { e = exs.get(0); } if (isSpecialException(e, this)) { return e.getHighestReceivedVersion(); } else { return this.version; } }