/** * Canonicalize an ordered set of exceptions. In the canonical form, none of the RVVExceptions * have any received versions. * * @param exceptions * @return The canonicalized set of exceptions. */ protected List<RVVException> canonicalExceptions(List<RVVException> exceptions) { LinkedList<RVVException> canon = new LinkedList<RVVException>(); if (exceptions != null) { // Iterate through the set of exceptions for (RVVException exception : exceptions) { if (exception.isEmpty()) { canon.add(exception); } else { long previous = exception.previousVersion; // Iterate through the set of received versions for this exception int insertAt = canon.size(); for (ReceivedVersionsIterator it = exception.receivedVersionsIterator(); it.hasNext(); ) { Long received = it.next(); // If we find a gap between the previous received version and the // next received version, add an exception. if (received != previous + 1) { canon.add(insertAt, RVVException.createException(previous, received)); } // move the previous reference previous = received; } // if there is a gap between the last received version and the next // version, add an exception // this also handles the case where the RVV has no received versions, // because previous==exception.previousVersion in that case. if (exception.nextVersion != previous + 1) { canon.add(insertAt, RVVException.createException(previous, exception.nextVersion)); } } } } return canon; }
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; } }
/** Add an exception that is older than this.bitSetVersion. */ protected synchronized void addException(long previousVersion, long nextVersion) { if (this.exceptions == null) { this.exceptions = new LinkedList<RVVException>(); } int i = 0; for (Iterator<RVVException> it = this.exceptions.iterator(); it.hasNext(); i++) { RVVException e = it.next(); if (previousVersion >= e.nextVersion) { RVVException except = RVVException.createException(previousVersion, nextVersion); this.exceptions.add(i, except); return; } } this.exceptions.add(RVVException.createException(previousVersion, nextVersion)); }
@Override public synchronized RegionVersionHolder<T> clone() { RegionVersionHolder<T> clone = new RegionVersionHolder<T>(this.version); clone.id = this.id; clone.isDepartedMember = this.isDepartedMember; if (this.exceptions != null) { clone.exceptions = new LinkedList<RVVException>(); for (RVVException e : this.exceptions) { clone.exceptions.add(e.clone()); } } if (this.bitSet != null) { clone.bitSet = (BitSet) this.bitSet.clone(); clone.bitSetVersion = this.bitSetVersion; clone.mergeBitSet(); } return clone; }
/** * Initialize this version holder from another version holder This is called during GII. * * <p>It's more likely that the other holder has seen most of the versions, and this version * holder only has a few updates that happened since the GII started. So we apply our seen * versions to the other version holder and then initialize this version holder from the other * version holder. */ public synchronized void initializeFrom(RegionVersionHolder<T> source) { // Make sure the bitsets are merged in both the source // and this vector mergeBitSet(); RegionVersionHolder<T> other = source.clone(); other.mergeBitSet(); // Get a copy of the local version and exceptions long myVersion = this.version; // initialize our version and exceptions to match the others this.exceptions = other.exceptions; this.version = other.version; // Initialize the bit set to be empty. Merge bit set should // have already done this, but just to be sure. if (this.bitSet != null) { this.bitSetVersion = this.version; // Make sure the bit set is empty except for the first, bit, indicating // that the version has been received. this.bitSet.set(0); } // Now if this.version/exceptions overlap with myVersion/myExceptions, use this' // The only case needs special handling is: if myVersion is newer than this.version, // should create an exception (this.version+1, myversion) and set this.version=myversion if (myVersion > this.version) { RVVException e = RVVException.createException(this.version, myVersion + 1); // add special exception if (this.exceptions == null) { this.exceptions = new LinkedList<RVVException>(); } int i = 0; for (RVVException exception : this.exceptions) { if (e.compareTo(exception) >= 0) { break; } i++; } this.exceptions.add(i, e); this.version = myVersion; } }
/* (non-Javadoc) * @see com.gemstone.gemfire.DataSerializable#fromData(java.io.DataInput) */ public void fromData(DataInput in) throws IOException { this.version = InternalDataSerializer.readUnsignedVL(in); int size = (int) InternalDataSerializer.readUnsignedVL(in); this.isDepartedMember = in.readBoolean(); if (size > 0) { this.exceptions = new LinkedList<RVVException>(); for (int i = 0; i < size; i++) { RVVException e = RVVException.createException(in); this.exceptions.add(e); } } }
/** * Returns true if this version hold has an exception in the exception list for the given version * number. * * <p>This differs from contains because it returns true if v is greater than the last seen * version for this holder. */ synchronized boolean hasExceptionFor(long v) { if (this.bitSet != null && v >= this.bitSetVersion) { if (v > this.bitSetVersion + this.bitSet.length()) { return false; } return this.bitSet.get((int) (v - this.bitSetVersion)); } if (this.exceptions == null) { return false; } for (Iterator<RVVException> it = this.exceptions.iterator(); it.hasNext(); ) { RVVException e = it.next(); if (e.nextVersion <= v) { return false; // there is no RVVException for this version } if (e.previousVersion < v && v < e.nextVersion) { return !e.contains(v); } } return false; }
/** add a version that is older than this.bitSetVersion */ private void addOlderVersion(long missingVersion) { // exceptions iterate in reverse order on their previousVersion variable if (this.exceptions == null) { return; } int i = 0; for (Iterator<RVVException> it = this.exceptions.iterator(); it.hasNext(); ) { RVVException e = it.next(); if (e.nextVersion <= missingVersion) { return; // there is no RVVException for this version } if (e.previousVersion < missingVersion && missingVersion < e.nextVersion) { String fine = null; if (logger.isTraceEnabled(LogMarker.RVV)) { fine = e.toString(); } e.add(missingVersion); if (e.isFilled()) { if (fine != null) { logger.trace(LogMarker.RVV, "Filled exception {}", fine); } it.remove(); } else if (e.shouldChangeForm()) { this.exceptions.set(i, e.changeForm()); } if (this.exceptions.isEmpty()) { this.exceptions = null; } return; } i++; } }