Search in sources :

Example 1 with MultiSMREntry

use of org.corfudb.protocols.logprotocol.MultiSMREntry 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);
    }
}
Also used : CheckpointEntry(org.corfudb.protocols.logprotocol.CheckpointEntry) TokenResponse(org.corfudb.protocols.wireprotocol.TokenResponse) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) SMREntry(org.corfudb.protocols.logprotocol.SMREntry) BackpointerStreamView(org.corfudb.runtime.view.stream.BackpointerStreamView) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry)

Example 2 with MultiSMREntry

use of org.corfudb.protocols.logprotocol.MultiSMREntry 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");
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) SMRMap(org.corfudb.runtime.collections.SMRMap) Semaphore(java.util.concurrent.Semaphore) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) SMREntry(org.corfudb.protocols.logprotocol.SMREntry) MultiObjectSMREntry(org.corfudb.protocols.logprotocol.MultiObjectSMREntry) MultiObjectSMREntry(org.corfudb.protocols.logprotocol.MultiObjectSMREntry) TypeToken(com.google.common.reflect.TypeToken) CorfuRuntime(org.corfudb.runtime.CorfuRuntime) IStreamView(org.corfudb.runtime.view.stream.IStreamView) Test(org.junit.Test)

Example 3 with MultiSMREntry

use of org.corfudb.protocols.logprotocol.MultiSMREntry 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");
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) SMREntry(org.corfudb.protocols.logprotocol.SMREntry) MultiObjectSMREntry(org.corfudb.protocols.logprotocol.MultiObjectSMREntry) MultiObjectSMREntry(org.corfudb.protocols.logprotocol.MultiObjectSMREntry) IStreamView(org.corfudb.runtime.view.stream.IStreamView) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) Test(org.junit.Test)

Example 4 with MultiSMREntry

use of org.corfudb.protocols.logprotocol.MultiSMREntry in project CorfuDB by CorfuDB.

the class CheckpointWriter method appendObjectState.

/** Append zero or more CONTINUATION records to this
     *  object's stream.  Each will contain a fraction of
     *  the state of the object that we're checkpointing
     *  (up to batchSize items at a time).
     *
     *  Corfu client transaction management, if desired, is the
     *  caller's responsibility.
     *
     *  The Iterators class appears to preserve the laziness
     *  of Stream processing; we don't wish to use more
     *  memory than strictly necessary to generate the
     *  checkpoint.  NOTE: It would be even more useful if
     *  the map had a lazy iterator: the eagerness of
     *  map.keySet().stream() is not ideal, but at least
     *  it should be much smaller than the entire map.
     *
     *  NOTE: The postAppendFunc lambda is executed in the
     *  current thread context, i.e., inside of a Corfu
     *  transaction, and that transaction will be *aborted*
     *  at the end of this function.  Any Corfu data
     *  modifying ops will be undone by the TXAbort().
     *
     * @return Stream of global log addresses of the
     * CONTINUATION records written.
     */
public List<Long> appendObjectState() {
    ImmutableMap<CheckpointEntry.CheckpointDictKey, String> mdKV = ImmutableMap.copyOf(this.mdKV);
    List<Long> continuationAddresses = new ArrayList<>();
    Iterators.partition(map.keySet().stream().map(k -> {
        return new SMREntry("put", new Object[] { keyMutator.apply(k), valueMutator.apply(map.get(k)) }, serializer);
    }).iterator(), batchSize).forEachRemaining(entries -> {
        MultiSMREntry smrEntries = new MultiSMREntry();
        for (int i = 0; i < ((List) entries).size(); i++) {
            smrEntries.addTo((SMREntry) ((List) entries).get(i));
        }
        CheckpointEntry cp = new CheckpointEntry(CheckpointEntry.CheckpointEntryType.CONTINUATION, author, checkpointID, mdKV, smrEntries);
        long pos = sv.append(Collections.singleton(streamID), cp, null);
        postAppendFunc.accept(cp, pos);
        continuationAddresses.add(pos);
        numEntries++;
        numBytes += cp.getSmrEntriesBytes();
    });
    return continuationAddresses;
}
Also used : Setter(lombok.Setter) java.util(java.util) TransactionalContext(org.corfudb.runtime.object.transactions.TransactionalContext) Getter(lombok.Getter) ImmutableMap(com.google.common.collect.ImmutableMap) LocalDateTime(java.time.LocalDateTime) AbstractTransactionalContext(org.corfudb.runtime.object.transactions.AbstractTransactionalContext) SMRMap(org.corfudb.runtime.collections.SMRMap) StreamsView(org.corfudb.runtime.view.StreamsView) Function(java.util.function.Function) Iterators(com.google.common.collect.Iterators) CheckpointEntry(org.corfudb.protocols.logprotocol.CheckpointEntry) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) Consumer(java.util.function.Consumer) SMREntry(org.corfudb.protocols.logprotocol.SMREntry) TokenResponse(org.corfudb.protocols.wireprotocol.TokenResponse) BiConsumer(java.util.function.BiConsumer) TransactionType(org.corfudb.runtime.object.transactions.TransactionType) ISerializer(org.corfudb.util.serializer.ISerializer) Serializers(org.corfudb.util.serializer.Serializers) CheckpointEntry(org.corfudb.protocols.logprotocol.CheckpointEntry) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) MultiSMREntry(org.corfudb.protocols.logprotocol.MultiSMREntry) SMREntry(org.corfudb.protocols.logprotocol.SMREntry)

Aggregations

MultiSMREntry (org.corfudb.protocols.logprotocol.MultiSMREntry)4 SMREntry (org.corfudb.protocols.logprotocol.SMREntry)4 CheckpointEntry (org.corfudb.protocols.logprotocol.CheckpointEntry)2 MultiObjectSMREntry (org.corfudb.protocols.logprotocol.MultiObjectSMREntry)2 ILogData (org.corfudb.protocols.wireprotocol.ILogData)2 TokenResponse (org.corfudb.protocols.wireprotocol.TokenResponse)2 SMRMap (org.corfudb.runtime.collections.SMRMap)2 IStreamView (org.corfudb.runtime.view.stream.IStreamView)2 Test (org.junit.Test)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterators (com.google.common.collect.Iterators)1 TypeToken (com.google.common.reflect.TypeToken)1 LocalDateTime (java.time.LocalDateTime)1 java.util (java.util)1 Semaphore (java.util.concurrent.Semaphore)1 BiConsumer (java.util.function.BiConsumer)1 Consumer (java.util.function.Consumer)1 Function (java.util.function.Function)1 Getter (lombok.Getter)1 Setter (lombok.Setter)1