use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class AbstractRegionEntry method generateVersionTag.
/**
* This generates version tags for outgoing messages for all subclasses supporting concurrency
* versioning. It also sets the entry's version stamp to the tag's values.
*/
@Override
public VersionTag generateVersionTag(VersionSource member, boolean withDelta, LocalRegion region, EntryEventImpl event) {
VersionStamp stamp = this.getVersionStamp();
if (stamp != null && region.getServerProxy() == null) {
// clients do not generate versions
int v = stamp.getEntryVersion() + 1;
if (v > 0xFFFFFF) {
// roll-over
v -= 0x1000000;
}
VersionSource previous = stamp.getMemberID();
// space.
if (member == null) {
VersionSource regionMember = region.getVersionMember();
if (regionMember instanceof DiskStoreID) {
member = regionMember;
}
}
VersionTag tag = VersionTag.create(member);
tag.setEntryVersion(v);
if (region.getVersionVector() != null) {
// Use region version if already provided, else generate
long nextRegionVersion = event.getNextRegionVersion();
if (nextRegionVersion != -1) {
// Set on the tag and record it locally
tag.setRegionVersion(nextRegionVersion);
RegionVersionVector rvv = region.getVersionVector();
rvv.recordVersion(rvv.getOwnerId(), nextRegionVersion);
if (logger.isDebugEnabled()) {
logger.debug("recorded region version {}; region={}", nextRegionVersion, region.getFullPath());
}
} else {
tag.setRegionVersion(region.getVersionVector().getNextVersion());
}
}
if (withDelta) {
tag.setPreviousMemberID(previous);
}
VersionTag remoteTag = event.getVersionTag();
if (remoteTag != null && remoteTag.isGatewayTag()) {
// if this event was received from a gateway we use the remote system's
// timestamp and dsid.
tag.setVersionTimeStamp(remoteTag.getVersionTimeStamp());
tag.setDistributedSystemId(remoteTag.getDistributedSystemId());
tag.setAllowedByResolver(remoteTag.isAllowedByResolver());
} else {
long time = region.cacheTimeMillis();
int dsid = region.getDistributionManager().getDistributedSystemId();
// one received from a wan gateway, so fake a timestamp if necessary
if (time <= stamp.getVersionTimeStamp() && dsid != tag.getDistributedSystemId()) {
time = stamp.getVersionTimeStamp() + 1;
}
tag.setVersionTimeStamp(time);
tag.setDistributedSystemId(dsid);
}
stamp.setVersions(tag);
stamp.setMemberID(member);
event.setVersionTag(tag);
if (logger.isDebugEnabled()) {
logger.debug("generated tag {}; key={}; oldvalue={} newvalue={} client={} region={}; rvv={}", tag, event.getKey(), event.getOldValueStringForm(), event.getNewValueStringForm(), event.getContext() == null ? "none" : event.getContext().getDistributedMember().getName(), region.getFullPath(), region.getVersionVector());
}
return tag;
}
return null;
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class PartitionedRegion method getAllBucketEntries.
/**
* Test Method: Get all entries for all copies of a bucket
*
* This method will not work correctly if membership in the distributed system changes while the
* result is being calculated.
*
* @return a List of HashMaps, each map being a copy of the entries in a bucket
*/
public List<BucketDump> getAllBucketEntries(final int bucketId) throws ForceReattemptException {
if (bucketId >= getTotalNumberOfBuckets()) {
return Collections.emptyList();
}
ArrayList<BucketDump> ret = new ArrayList<BucketDump>();
HashSet<InternalDistributedMember> collected = new HashSet<InternalDistributedMember>();
for (; ; ) {
// Collect all the candidates by re-examining the advisor...
Set<InternalDistributedMember> owners = getRegionAdvisor().getBucketOwners(bucketId);
// Remove ones we've already polled...
owners.removeAll(collected);
// Terminate if no more entries
if (owners.isEmpty()) {
break;
}
// Get first entry
Iterator<InternalDistributedMember> ownersI = owners.iterator();
InternalDistributedMember owner = (InternalDistributedMember) ownersI.next();
// Remove it from our list
collected.add(owner);
// If it is ourself, answer directly
if (owner.equals(getMyId())) {
BucketRegion br = this.dataStore.handleRemoteGetEntries(bucketId);
Map<Object, Object> m = new HashMap<Object, Object>() {
// TODO: clean this up -- outer class is not serializable
private static final long serialVersionUID = 0L;
@Override
public String toString() {
return "Bucket id = " + bucketId + " from local member = " + getDistributionManager().getDistributionManagerId() + ": " + super.toString();
}
};
Map<Object, VersionTag> versions = new HashMap<Object, VersionTag>();
for (Iterator<Map.Entry> it = br.entrySet().iterator(); it.hasNext(); ) {
LocalRegion.NonTXEntry entry = (LocalRegion.NonTXEntry) it.next();
RegionEntry re = entry.getRegionEntry();
// OFFHEAP: incrc, deserialize, decrc
Object value = re.getValue(br);
VersionStamp versionStamp = re.getVersionStamp();
VersionTag versionTag = versionStamp != null ? versionStamp.asVersionTag() : null;
if (versionTag != null) {
versionTag.replaceNullIDs(br.getVersionMember());
}
if (Token.isRemoved(value)) {
continue;
} else if (Token.isInvalid(value)) {
value = null;
} else if (value instanceof CachedDeserializable) {
value = ((CachedDeserializable) value).getDeserializedForReading();
}
m.put(re.getKey(), value);
versions.put(re.getKey(), versionTag);
}
RegionVersionVector rvv = br.getVersionVector();
rvv = rvv != null ? rvv.getCloneForTransmission() : null;
ret.add(new BucketDump(bucketId, owner, rvv, m, versions));
continue;
}
// Send a message
try {
final FetchEntriesResponse r;
r = FetchEntriesMessage.send(owner, this, bucketId);
ret.add(r.waitForEntries());
} catch (ForceReattemptException ignore) {
// node has departed? Ignore.
}
}
return ret;
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class LocalRegion method clearRegionLocally.
/**
* Common code used by both clear and localClear. On the lines of destroyRegion, this method will
* be invoked for clearing the local cache.The cmnClearRegion will be overridden in the derived
* class DistributedRegion too. For clear operation , no CacheWriter will be invoked . It will
* only have afterClear callback. Also like destroyRegion & invalidateRegion , the clear operation
* will not take distributedLock. The clear operation will also clear the local tranxnl entries .
* The clear operation will have immediate committed state.
*/
void clearRegionLocally(RegionEventImpl regionEvent, boolean cacheWrite, RegionVersionVector vector) {
final boolean isRvvDebugEnabled = logger.isTraceEnabled(LogMarker.RVV);
RegionVersionVector rvv = vector;
if (this.serverRegionProxy != null) {
// clients and local regions do not maintain a full RVV. can't use it with clear()
rvv = null;
}
if (rvv != null && this.dataPolicy.withStorage()) {
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "waiting for my version vector to dominate{}mine={}{} other={}", getLineSeparator(), getLineSeparator(), this.versionVector.fullToString(), rvv);
}
boolean result = this.versionVector.waitToDominate(rvv, this);
if (!result) {
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "incrementing clearTimeouts for {} rvv={}", getName(), this.versionVector.fullToString());
}
getCachePerfStats().incClearTimeouts();
}
}
// If the initial image operation is still in progress then we need will have to do the clear
// operation at the end of the GII.For this we try to acquire the lock of GII the boolean
// returned is true that means lock was obtained which also means that GII is still in progress.
boolean isGIIinProgress = lockGII();
if (isGIIinProgress) {
// Also we should try & abort the GII
try {
getImageState().setClearRegionFlag(true, /* Clear region */
rvv);
} finally {
unlockGII();
}
}
if (cacheWrite && !isGIIinProgress) {
this.cacheWriteBeforeRegionClear(regionEvent);
}
RegionVersionVector myVector = getVersionVector();
if (myVector != null) {
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "processing version information for {}", regionEvent);
}
if (!regionEvent.isOriginRemote() && !regionEvent.getOperation().isLocal()) {
// generate a new version for the operation
VersionTag tag = VersionTag.create(getVersionMember());
tag.setVersionTimeStamp(cacheTimeMillis());
tag.setRegionVersion(myVector.getNextVersionWhileLocked());
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "generated version tag for clear: {}", tag);
}
regionEvent.setVersionTag(tag);
} else {
VersionTag tag = regionEvent.getVersionTag();
if (tag != null) {
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "recording version tag for clear: {}", tag);
}
// clear() events always have the ID in the tag
myVector.recordVersion(tag.getMemberID(), tag);
}
}
}
// Clear the expiration task for all the entries. It is possible that
// after clearing it some new entries may get added before issuing clear
// on the map , but that should be OK, as the expiration thread will
// silently move ahead if the entry to be expired no longer existed
this.cancelAllEntryExpiryTasks();
if (this.entryUserAttributes != null) {
this.entryUserAttributes.clear();
}
// be set to the current vector versions
if (rvv == null && myVector != null) {
myVector.removeOldVersions();
}
// clear the disk region if present
if (this.diskRegion != null) {
// persist current rvv and rvvgc which contained version for clear() itself
if (this.getDataPolicy().withPersistence()) {
// null means not to change dr.rvvTrust
if (isRvvDebugEnabled) {
logger.trace(LogMarker.RVV, "Clear: Saved current rvv: {}", this.diskRegion.getRegionVersionVector());
}
this.diskRegion.writeRVV(this, null);
this.diskRegion.writeRVVGC(this);
}
// clear the entries in disk
this.diskRegion.clear(this, rvv);
} else // this will be done in diskRegion.clear if it is not null else it has to be
// done here
{
// Now remove the tx entries for this region
txClearRegion();
// Now clear the map of committed entries
Set<VersionSource> remainingIDs = clearEntries(rvv);
if (!this.dataPolicy.withPersistence()) {
// persistent regions do not reap IDs
if (myVector != null) {
myVector.removeOldMembers(remainingIDs);
}
}
}
if (!isProxy()) {
// TODO made indexManager variable is made volatile. Is it necessary?
if (this.indexManager != null) {
try {
this.indexManager.rerunIndexCreationQuery();
} catch (QueryException qe) {
// TODO: never throw an annonymous class (and outer-class is not serializable)
throw new CacheRuntimeException(LocalizedStrings.LocalRegion_EXCEPTION_OCCURRED_WHILE_RE_CREATING_INDEX_DATA_ON_CLEARED_REGION.toLocalizedString(), qe) {
private static final long serialVersionUID = 0L;
};
}
}
}
if (ISSUE_CALLBACKS_TO_CACHE_OBSERVER) {
CacheObserverHolder.getInstance().afterRegionClear(regionEvent);
}
if (isGIIinProgress) {
return;
}
regionEvent.setEventType(EnumListenerEvent.AFTER_REGION_CLEAR);
// Issue a callback to afterClear if the region is initialized
boolean hasListener = hasListener();
if (hasListener) {
dispatchListenerEvent(EnumListenerEvent.AFTER_REGION_CLEAR, regionEvent);
}
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class MultiVMRegionTestCase method getVersionVector.
private RegionVersionVector getVersionVector(VM vm) throws Exception {
byte[] serializedForm = (byte[]) vm.invoke(() -> this.getCCRegionVersionVector());
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(serializedForm));
return (RegionVersionVector) DataSerializer.readObject(dis);
}
use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.
the class GIIDeltaDUnitTest method checkIfFullGII.
private void checkIfFullGII(VM vm, final String regionName, final byte[] remote_rvv_bytearray, final boolean expectFullGII) {
SerializableRunnable checkIfFullGII = new SerializableRunnable("check if full gii") {
public void run() {
DistributedRegion rr = (DistributedRegion) getCache().getRegion(regionName);
ByteArrayInputStream bais = new ByteArrayInputStream(remote_rvv_bytearray);
RegionVersionVector remote_rvv = null;
try {
remote_rvv = DataSerializer.readObject(new DataInputStream(bais));
} catch (IOException e) {
Assert.fail("Unexpected exception", e);
} catch (ClassNotFoundException e) {
Assert.fail("Unexpected exception", e);
}
RequestImageMessage rim = new RequestImageMessage();
rim.setSender(R_ID);
boolean isFullGII = rim.goWithFullGII(rr, remote_rvv);
assertEquals(expectFullGII, isFullGII);
}
};
vm.invoke(checkIfFullGII);
}
Aggregations