use of org.infinispan.container.entries.VersionedRepeatableReadEntry in project infinispan by infinispan.
the class WriteSkewHelper method performWriteSkewCheckAndReturnNewVersions.
public static CompletionStage<Map<Object, IncrementableEntryVersion>> performWriteSkewCheckAndReturnNewVersions(VersionedPrepareCommand prepareCommand, EntryLoader<?, ?> entryLoader, VersionGenerator versionGenerator, TxInvocationContext<?> context, KeySpecificLogic ksl, KeyPartitioner keyPartitioner) {
if (prepareCommand.getVersionsSeen() == null) {
// Do not perform the write skew check if this prepare command is being replayed for state transfer
return CompletableFutures.completedEmptyMap();
}
Map<Object, IncrementableEntryVersion> uv = new HashMap<>();
AggregateCompletionStage<Map<Object, IncrementableEntryVersion>> aggregateCompletionStage = CompletionStages.aggregateCompletionStage(uv);
for (WriteCommand c : prepareCommand.getModifications()) {
for (Object k : c.getAffectedKeys()) {
int segment = SegmentSpecificCommand.extractSegment(c, k, keyPartitioner);
if (ksl.performCheckOnSegment(segment)) {
CacheEntry<?, ?> cacheEntry = context.lookupEntry(k);
if (!(cacheEntry instanceof VersionedRepeatableReadEntry)) {
continue;
}
VersionedRepeatableReadEntry entry = (VersionedRepeatableReadEntry) cacheEntry;
CompletionStage<Boolean> skewStage = entry.performWriteSkewCheck(entryLoader, segment, context, prepareCommand.getVersionsSeen().get(k), versionGenerator, c.hasAnyFlag(FlagBitSets.ROLLING_UPGRADE));
aggregateCompletionStage.dependsOn(skewStage.thenAccept(passSkew -> {
if (!passSkew) {
throw new WriteSkewException("Write skew detected on key " + entry.getKey() + " for transaction " + context.getCacheTransaction(), entry.getKey());
}
IncrementableEntryVersion newVersion = incrementVersion(entry, versionGenerator);
// Have to synchronize as we could have returns on different threads due to notifications/loaders etc
synchronized (uv) {
uv.put(entry.getKey(), newVersion);
}
}));
}
}
}
return aggregateCompletionStage.freeze();
}
use of org.infinispan.container.entries.VersionedRepeatableReadEntry in project infinispan by infinispan.
the class EntryFactoryImpl method createWrappedEntry.
protected MVCCEntry<?, ?> createWrappedEntry(Object key, CacheEntry<?, ?> cacheEntry) {
Object value = null;
Metadata metadata = null;
PrivateMetadata internalMetadata = null;
if (cacheEntry != null) {
synchronized (cacheEntry) {
value = cacheEntry.getValue();
metadata = cacheEntry.getMetadata();
internalMetadata = cacheEntry.getInternalMetadata();
}
}
if (log.isTraceEnabled())
log.tracef("Creating new entry for key %s", toStr(key));
MVCCEntry<?, ?> mvccEntry;
if (useRepeatableRead) {
if (useVersioning) {
if (internalMetadata == null) {
internalMetadata = nonExistingPrivateMetadata;
}
mvccEntry = new VersionedRepeatableReadEntry(key, value, metadata);
} else {
mvccEntry = new RepeatableReadEntry(key, value, metadata);
}
} else {
mvccEntry = new ReadCommittedEntry(key, value, metadata);
}
mvccEntry.setInternalMetadata(internalMetadata);
if (cacheEntry != null) {
mvccEntry.setCreated(cacheEntry.getCreated());
mvccEntry.setLastUsed(cacheEntry.getLastUsed());
}
return mvccEntry;
}
Aggregations