Search in sources :

Example 6 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class AbstractContextStreamView method nextUpTo.

/**
     * {@inheritDoc}
     */
@Override
public final synchronized ILogData nextUpTo(final long maxGlobal) {
    // pointer.
    if (getCurrentContext().globalPointer > maxGlobal) {
        return null;
    }
    // Pop the context if it has changed.
    if (getCurrentContext().globalPointer >= getCurrentContext().maxGlobalAddress) {
        final T last = streamContexts.pollFirst();
        log.trace("Completed context {}@{}, removing.", last.id, last.maxGlobalAddress);
    }
    // Get the next entry from the underlying implementation.
    final ILogData entry = getNextEntry(getCurrentContext(), maxGlobal);
    if (entry != null) {
        // Update the pointer.
        updatePointer(entry);
        // context.
        if (processEntryForContext(entry)) {
            return nextUpTo(maxGlobal);
        }
    }
    // Return the entry.
    return entry;
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData)

Example 7 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class AbstractQueuedStreamView method getNextEntry.

/**
     * {@inheritDoc}
     */
@Override
protected ILogData getNextEntry(QueuedStreamContext context, long maxGlobal) {
    // Return if the queue is still empty.
    if (context.readQueue.isEmpty() && context.readCpQueue.isEmpty() && !fillReadQueue(maxGlobal, context)) {
        return null;
    }
    // If checkpoint data is available, get from readCpQueue first
    NavigableSet<Long> getFrom;
    if (context.readCpQueue.size() > 0) {
        getFrom = context.readCpQueue;
        if (context.readQueue.isEmpty()) {
            // readQueue is empty, readCpQueue is not.
            // This is a case where we have had 2 checkpoints
            // adjacent to each other, and no non-checkpoint
            // entries in the stream in between the checkpoints
            // or during the 2nd checkpoint.  Processing of
            // checkpoint entries will not advance our context
            // globalPointer, only regular entries in readQueue.
            // However, we know that readQueue is *empty*, so
            // we advance globalPointer here.
            context.globalPointer = maxGlobal;
        }
    } else {
        getFrom = context.readQueue;
    }
    // to return.
    if (context.readCpQueue.isEmpty() && context.readQueue.first() > maxGlobal) {
        return null;
    }
    // have to perform several reads.
    while (getFrom.size() > 0) {
        final long thisRead = getFrom.pollFirst();
        ILogData ld = read(thisRead);
        if (ld.containsStream(context.id)) {
            // Only add to resolved if ld is from readQueue
            if (getFrom == context.readQueue) {
                addToResolvedQueue(context, thisRead, ld);
            }
            return ld;
        }
    }
    // stream, so we return null.
    return null;
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData)

Example 8 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class BackpointerStreamView method fillReadQueue.

/**
     * {@inheritDoc}
     */
@Override
protected boolean fillReadQueue(final long maxGlobal, final QueuedStreamContext context) {
    log.trace("Read_Fill_Queue[{}] Max: {}, Current: {}, Resolved: {} - {}", this, maxGlobal, context.globalPointer, context.maxResolution, context.minResolution);
    // considerCheckpoint: Use context.globalPointer as a signal of caller's intent:
    // if globalPointer == -1, then the caller needs to replay the stream from the
    // beginning because the caller has never read anything from the stream before.
    // Thus, it could be a significant time & I/O saving for the client to playback
    // from the latest checkpoint.
    // On the other hand, if not -1, then we assume that the caller has already
    // found the stream head and replayed some/all of it.
    //
    // We assume a "typical" case where the client probably needs to discover & replay
    // just a few log entries, whereas the checkpoint data that this method may discover
    // may be "huge" ... thus we favor ignoring the checkpoint data.  Such an assumption
    // may be invalid for very small SMR objects, such as a simple counter, where
    // checkpoint size would always be small enough to use checkpoint data instead of
    // continuing backward to find individual updates.
    boolean considerCheckpoint = context.globalPointer == -1;
    // The maximum address we will fill to.
    final long maxAddress = Long.min(maxGlobal, context.maxGlobalAddress);
    // we return since there is nothing left to do.
    if (context.globalPointer > maxAddress) {
        return false;
    }
    // queue, use it
    if (context.maxResolution > maxAddress && context.minResolution < context.globalPointer) {
        return fillFromResolved(maxGlobal, context);
    }
    Long latestTokenValue = null;
    // If the max has been resolved, use it.
    if (maxGlobal != Address.MAX) {
        latestTokenValue = context.resolvedQueue.ceiling(maxGlobal);
    }
    // a linearized read, fetch the token from the sequencer.
    if (latestTokenValue == null || maxGlobal == Address.MAX) {
        latestTokenValue = runtime.getSequencerView().nextToken(Collections.singleton(context.id), 0).getToken().getTokenValue();
    }
    // If there is no infomation on the tail of the stream, return, there is nothing to do
    if (Address.nonAddress(latestTokenValue)) {
        // curretly, the only possible non-address return value for a token-query is Address.NON_EXIST
        if (latestTokenValue != Address.NON_EXIST)
            log.warn("TOKEN[{}] unexpected return value", latestTokenValue);
        return false;
    }
    // queue, use it
    if (context.maxResolution > latestTokenValue && context.minResolution < context.globalPointer) {
        return fillFromResolved(latestTokenValue, context);
    }
    // Now we start traversing backpointers, if they are available. We
    // start at the latest token and go backward, until we reach the
    // log pointer. For each address which is less than
    // maxGlobalAddress, we insert it into the read queue.
    long currentRead = latestTokenValue;
    while (currentRead > context.globalPointer && Address.isAddress(currentRead)) {
        // We've somehow reached a read we already know about.
        if (context.readQueue.contains(currentRead)) {
            break;
        }
        log.trace("Read_Fill_Queue[{}] Read {}", this, currentRead);
        // Read the entry in question.
        ILogData currentEntry = runtime.getAddressSpaceView().read(currentRead);
        // we add it to the read queue.
        if (currentEntry.containsStream(context.id)) {
            if (currentEntry.hasCheckpointMetadata()) {
                examineCheckpointRecord(context, currentEntry, considerCheckpoint, currentRead);
            } else {
                context.readQueue.add(currentRead);
            }
        }
        // that the caller wants us to us, then we're done here.
        if (considerCheckpoint && currentRead <= context.checkpointSuccessStartAddr) {
            log.trace("Read_Fill_Queue[{}]: currentRead {} checkpointSuccessStartAddr {}", this, currentRead, context.checkpointSuccessStartAddr);
            break;
        }
        // queue, use it
        if (context.maxResolution > currentRead && context.minResolution < context.globalPointer) {
            return fillFromResolved(latestTokenValue, context);
        }
        // use it.
        if (context.minResolution <= context.globalPointer) {
            fillFromResolved(maxGlobal, context);
        }
        // If we have a backpointer, we'll use that for our next read.
        if (!runtime.backpointersDisabled && currentEntry.hasBackpointer(context.id)) {
            log.trace("Read_Fill_Queue[{}] Backpointer {}->{}", this, currentRead, currentEntry.getBackpointer(context.id));
            currentRead = currentEntry.getBackpointer(context.id);
        } else // Otherwise, our next read is the previous entry.
        {
            currentRead = currentRead - 1L;
        }
        // we need to stop.
        if (context.maxResolution >= currentRead) {
            break;
        }
    }
    log.debug("Read_Fill_Queue[{}] Filled CP queue with {}", this, context.readCpQueue);
    log.debug("Read_Fill_Queue[{}] Filled queue with {}", this, context.readQueue);
    return !context.readCpQueue.isEmpty() || !context.readQueue.isEmpty();
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData)

Example 9 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class StreamSpliterator method tryAdvance.

/** {@inheritDoc} */
@Override
public boolean tryAdvance(Consumer<? super ILogData> action) {
    // Get the next entry in the stream.
    ILogData next = streamView.nextUpTo(maxGlobal);
    // If null, end.
    if (next == null) {
        return false;
    }
    // Otherwise, apply
    action.accept(next);
    return true;
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData)

Example 10 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class AbstractReplicationProtocolTest method canWriteRead.

/** Check if we can write and then read the value
     * that was written.
     */
@Test
@SuppressWarnings("unchecked")
public void canWriteRead() throws Exception {
    setupNodes();
    //begin tests
    final CorfuRuntime r = getDefaultRuntime();
    final IReplicationProtocol rp = getProtocol();
    final Layout layout = r.getLayoutView().getLayout();
    LogData data = getLogData(0, "hello world".getBytes());
    rp.write(layout, data);
    ILogData read = rp.read(layout, 0);
    assertThat(read.getType()).isEqualTo(DataType.DATA);
    assertThat(read.getGlobalAddress()).isEqualTo(0);
    assertThat(read.getPayload(r)).isEqualTo("hello world".getBytes());
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) Layout(org.corfudb.runtime.view.Layout) CorfuRuntime(org.corfudb.runtime.CorfuRuntime) Test(org.junit.Test) AbstractViewTest(org.corfudb.runtime.view.AbstractViewTest)

Aggregations

ILogData (org.corfudb.protocols.wireprotocol.ILogData)27 LogData (org.corfudb.protocols.wireprotocol.LogData)9 Test (org.junit.Test)9 CorfuRuntime (org.corfudb.runtime.CorfuRuntime)8 Layout (org.corfudb.runtime.view.Layout)4 UUID (java.util.UUID)3 Nonnull (javax.annotation.Nonnull)3 SMREntry (org.corfudb.protocols.logprotocol.SMREntry)3 ReadResponse (org.corfudb.protocols.wireprotocol.ReadResponse)3 OverwriteException (org.corfudb.runtime.exceptions.OverwriteException)3 QuorumUnreachableException (org.corfudb.runtime.exceptions.QuorumUnreachableException)3 AbstractViewTest (org.corfudb.runtime.view.AbstractViewTest)3 QuorumFuturesFactory (org.corfudb.runtime.view.QuorumFuturesFactory)3 IStreamView (org.corfudb.runtime.view.stream.IStreamView)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 MultiObjectSMREntry (org.corfudb.protocols.logprotocol.MultiObjectSMREntry)2 MultiSMREntry (org.corfudb.protocols.logprotocol.MultiSMREntry)2 IMetadata (org.corfudb.protocols.wireprotocol.IMetadata)2 LogUnitClient (org.corfudb.runtime.clients.LogUnitClient)2 DataOutrankedException (org.corfudb.runtime.exceptions.DataOutrankedException)2