use of org.corfudb.protocols.logprotocol.SMREntry in project CorfuDB by CorfuDB.
the class OptimisticTransactionalContext method getUpcallResult.
/**
* if a Corfu object's method is an Accessor-Mutator, then although the mutation is delayed,
* it needs to obtain the result by invoking getUpcallResult() on the optimistic stream.
*
* This is similar to the second stage of access(), accept working on the optimistic stream instead of the
* underlying stream.- grabs the write-lock on the proxy.
* - uses proxy.setAsOptimisticStream in order to set itself as the proxy optimistic context,
* including rolling-back current optimistic changes, if any.
* - uses proxy.syncObjectUnsafe to bring the proxy to the desired version,
* which includes applying optimistic updates of the current
* transactional context.
*
* {@inheritDoc}
*/
@Override
public <T> Object getUpcallResult(ICorfuSMRProxyInternal<T> proxy, long timestamp, Object[] conflictObject) {
// Getting an upcall result adds the object to the conflict set.
addToReadSet(proxy, conflictObject);
// if we have a result, return it.
SMREntry wrapper = getWriteSetEntryList(proxy.getStreamID()).get((int) timestamp);
if (wrapper != null && wrapper.isHaveUpcallResult()) {
return wrapper.getUpcallResult();
}
// Otherwise, we need to sync the object
return proxy.getUnderlyingObject().update(o -> {
setAsOptimisticStream(o);
log.trace("Upcall[{}] {} Sync'd", this, timestamp);
o.syncObjectUnsafe(getSnapshotTimestamp());
SMREntry wrapper2 = getWriteSetEntryList(proxy.getStreamID()).get((int) timestamp);
if (wrapper2 != null && wrapper2.isHaveUpcallResult()) {
return wrapper2.getUpcallResult();
}
throw new RuntimeException("Tried to get upcall during a transaction but" + " we don't have it even after an optimistic sync (asked for " + timestamp + " we have 0-" + (getWriteSetEntryList(proxy.getStreamID()).size() - 1) + ")");
});
}
use of org.corfudb.protocols.logprotocol.SMREntry in project CorfuDB by CorfuDB.
the class CheckpointSmokeTest method writeCheckpointRecords.
private void writeCheckpointRecords(UUID streamId, String checkpointAuthor, UUID checkpointId, Object[] objects, Runnable l1, Runnable l2, boolean write1, boolean write2, boolean write3) throws Exception {
BackpointerStreamView sv = new BackpointerStreamView(r, streamId);
Map<CheckpointEntry.CheckpointDictKey, String> mdKV = new HashMap<>();
mdKV.put(CheckpointEntry.CheckpointDictKey.START_TIME, "The perfect time");
// Write cp #1 of 3
if (write1) {
TokenResponse tokResp1 = r.getSequencerView().nextToken(Collections.singleton(streamId), 0);
long addr1 = tokResp1.getToken().getTokenValue();
mdKV.put(CheckpointEntry.CheckpointDictKey.START_LOG_ADDRESS, Long.toString(addr1 + 1));
CheckpointEntry cp1 = new CheckpointEntry(CheckpointEntry.CheckpointEntryType.START, checkpointAuthor, checkpointId, mdKV, null);
sv.append(cp1, null, null);
}
// Interleaving opportunity #1
l1.run();
// Write cp #2 of 3
if (write2) {
MultiSMREntry smrEntries = new MultiSMREntry();
if (objects != null) {
for (int i = 0; i < objects.length; i++) {
smrEntries.addTo(new SMREntry("put", (Object[]) objects[i], Serializers.JSON));
}
}
CheckpointEntry cp2 = new CheckpointEntry(CheckpointEntry.CheckpointEntryType.CONTINUATION, checkpointAuthor, checkpointId, mdKV, smrEntries);
sv.append(cp2, null, null);
}
// Interleaving opportunity #2
l2.run();
// Write cp #3 of 3
if (write3) {
CheckpointEntry cp3 = new CheckpointEntry(CheckpointEntry.CheckpointEntryType.END, checkpointAuthor, checkpointId, mdKV, null);
sv.append(cp3, null, null);
}
}
use of org.corfudb.protocols.logprotocol.SMREntry in project CorfuDB by CorfuDB.
the class ObjectsViewTest method unrelatedStreamDoesNotConflict.
@Test
@SuppressWarnings("unchecked")
public void unrelatedStreamDoesNotConflict() throws Exception {
//begin tests
CorfuRuntime r = getDefaultRuntime();
Map<String, String> smrMap = r.getObjectsView().build().setStreamName("map a").setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).open();
IStreamView streamB = r.getStreamsView().get(CorfuRuntime.getStreamID("b"));
smrMap.put("a", "b");
streamB.append(new SMREntry("hi", new Object[] { "hello" }, Serializers.PRIMITIVE));
//this TX should not conflict
assertThat(smrMap).doesNotContainKey("b");
r.getObjectsView().TXBegin();
String b = smrMap.get("a");
smrMap.put("b", b);
r.getObjectsView().TXEnd();
assertThat(smrMap).containsEntry("b", "b");
}
use of org.corfudb.protocols.logprotocol.SMREntry in project CorfuDB by CorfuDB.
the class ObjectsViewTest method abortedTransactionDoesNotConflict.
@Test
@SuppressWarnings("unchecked")
public void abortedTransactionDoesNotConflict() throws Exception {
final String mapA = "map a";
//Enbale transaction logging
CorfuRuntime r = getDefaultRuntime().setTransactionLogging(true);
SMRMap<String, String> map = getDefaultRuntime().getObjectsView().build().setStreamName(mapA).setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).open();
// TODO: fix so this does not require mapCopy.
SMRMap<String, String> mapCopy = getDefaultRuntime().getObjectsView().build().setStreamName(mapA).setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).addOption(ObjectOpenOptions.NO_CACHE).open();
map.put("initial", "value");
Semaphore s1 = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
// Schedule two threads, the first starts a transaction and reads,
// then waits for the second thread to finish.
// the second starts a transaction, waits for the first tx to read
// and commits.
// The first thread then resumes and attempts to commit. It should abort.
scheduleConcurrently(1, t -> {
assertThatThrownBy(() -> {
getRuntime().getObjectsView().TXBegin();
map.get("k");
s1.release();
s2.acquire();
map.put("k", "v1");
getRuntime().getObjectsView().TXEnd();
}).isInstanceOf(TransactionAbortedException.class);
});
scheduleConcurrently(1, t -> {
s1.acquire();
getRuntime().getObjectsView().TXBegin();
mapCopy.put("k", "v2");
getRuntime().getObjectsView().TXEnd();
s2.release();
});
executeScheduled(2, PARAMETERS.TIMEOUT_LONG);
// The result should contain T2s modification.
assertThat(map).containsEntry("k", "v2");
IStreamView txStream = r.getStreamsView().get(ObjectsView.TRANSACTION_STREAM_ID);
List<ILogData> txns = txStream.remainingUpTo(Long.MAX_VALUE);
assertThat(txns).hasSize(1);
assertThat(txns.get(0).getLogEntry(getRuntime()).getType()).isEqualTo(LogEntry.LogEntryType.MULTIOBJSMR);
MultiObjectSMREntry tx1 = (MultiObjectSMREntry) txns.get(0).getLogEntry(getRuntime());
MultiSMREntry entryMap = tx1.getEntryMap().get(CorfuRuntime.getStreamID(mapA));
assertThat(entryMap).isNotNull();
assertThat(entryMap.getUpdates().size()).isEqualTo(1);
SMREntry smrEntry = entryMap.getUpdates().get(0);
Object[] args = smrEntry.getSMRArguments();
assertThat(smrEntry.getSMRMethod()).isEqualTo("put");
assertThat((String) args[0]).isEqualTo("k");
assertThat((String) args[1]).isEqualTo("v2");
}
use of org.corfudb.protocols.logprotocol.SMREntry in project CorfuDB by CorfuDB.
the class WriteAfterWriteTransactionContextTest method concurrentModificationsCauseAbort.
@Test
public void concurrentModificationsCauseAbort() {
getRuntime().setTransactionLogging(true);
getMap();
t(1, () -> write("k", "v1"));
t(1, this::WWTXBegin);
t(2, this::WWTXBegin);
t(1, () -> get("k"));
t(2, () -> get("k"));
t(1, () -> write("k", "v2"));
t(2, () -> write("k", "v3"));
t(1, this::TXEnd);
t(2, this::TXEnd).assertThrows().isInstanceOf(TransactionAbortedException.class);
assertThat(getMap()).containsEntry("k", "v2").doesNotContainEntry("k", "v3");
IStreamView txStream = getRuntime().getStreamsView().get(ObjectsView.TRANSACTION_STREAM_ID);
List<ILogData> txns = txStream.remainingUpTo(Long.MAX_VALUE);
assertThat(txns).hasSize(1);
assertThat(txns.get(0).getLogEntry(getRuntime()).getType()).isEqualTo(LogEntry.LogEntryType.MULTIOBJSMR);
MultiObjectSMREntry tx1 = (MultiObjectSMREntry) txns.get(0).getLogEntry(getRuntime());
assertThat(tx1.getEntryMap().size()).isEqualTo(1);
MultiSMREntry entryMap = tx1.getEntryMap().entrySet().iterator().next().getValue();
assertThat(entryMap).isNotNull();
assertThat(entryMap.getUpdates().size()).isEqualTo(1);
SMREntry smrEntry = entryMap.getUpdates().get(0);
Object[] args = smrEntry.getSMRArguments();
assertThat(smrEntry.getSMRMethod()).isEqualTo("put");
assertThat((String) args[0]).isEqualTo("k");
assertThat((String) args[1]).isEqualTo("v2");
}
Aggregations