Search in sources :

Example 1 with LogSegmentRandomAccessEntryReader

use of org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader in project bookkeeper by apache.

the class BKLogSegmentEntryStore method openRandomAccessReader.

@Override
public CompletableFuture<LogSegmentRandomAccessEntryReader> openRandomAccessReader(final LogSegmentMetadata segment, final boolean fence) {
    final BookKeeper bk;
    try {
        bk = this.bkc.get();
    } catch (IOException e) {
        return FutureUtils.exception(e);
    }
    final CompletableFuture<LogSegmentRandomAccessEntryReader> openPromise = new CompletableFuture<LogSegmentRandomAccessEntryReader>();
    AsyncCallback.OpenCallback openCallback = new AsyncCallback.OpenCallback() {

        @Override
        public void openComplete(int rc, LedgerHandle lh, Object ctx) {
            if (BKException.Code.OK != rc) {
                FutureUtils.completeExceptionally(openPromise, new BKTransmitException("Failed to open ledger handle for log segment " + segment, rc));
                return;
            }
            LogSegmentRandomAccessEntryReader reader = new BKLogSegmentRandomAccessEntryReader(segment, lh, conf);
            FutureUtils.complete(openPromise, reader);
        }
    };
    if (segment.isInProgress() && !fence) {
        bk.asyncOpenLedgerNoRecovery(segment.getLogSegmentId(), BookKeeper.DigestType.CRC32, passwd, openCallback, null);
    } else {
        bk.asyncOpenLedger(segment.getLogSegmentId(), BookKeeper.DigestType.CRC32, passwd, openCallback, null);
    }
    return openPromise;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) AsyncCallback(org.apache.bookkeeper.client.AsyncCallback) BKTransmitException(org.apache.distributedlog.exceptions.BKTransmitException) BookKeeper(org.apache.bookkeeper.client.BookKeeper) LogSegmentRandomAccessEntryReader(org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader) IOException(java.io.IOException)

Example 2 with LogSegmentRandomAccessEntryReader

use of org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader in project bookkeeper by apache.

the class ReadUtils method getLogRecordNotLessThanTxId.

// 
// Search Functions
// 
/**
 * Get the log record whose transaction id is not less than provided <code>transactionId</code>.
 *
 * <p>
 * It uses a binary-search like algorithm to find the log record whose transaction id is not less than
 * provided <code>transactionId</code> within a log <code>segment</code>. You could think of a log segment
 * in terms of a sequence of records whose transaction ids are non-decreasing.
 *
 * - The sequence of records within a log segment is divided into N pieces.
 * - Find the piece of records that contains a record whose transaction id is not less than provided
 *   <code>transactionId</code>.
 *
 * N could be chosen based on trading off concurrency and latency.
 * </p>
 *
 * @param logName
 *          name of the log
 * @param segment
 *          metadata of the log segment
 * @param transactionId
 *          transaction id
 * @param executorService
 *          executor service used for processing entries
 * @param entryStore
 *          log segment entry store
 * @param nWays
 *          how many number of entries to search in parallel
 * @return found log record. none if all transaction ids are less than provided <code>transactionId</code>.
 */
public static CompletableFuture<Optional<LogRecordWithDLSN>> getLogRecordNotLessThanTxId(final String logName, final LogSegmentMetadata segment, final long transactionId, final ExecutorService executorService, final LogSegmentEntryStore entryStore, final int nWays) {
    if (!segment.isInProgress()) {
        if (segment.getLastTxId() < transactionId) {
            // all log records whose transaction id is less than provided transactionId
            // then return none
            Optional<LogRecordWithDLSN> noneRecord = Optional.absent();
            return FutureUtils.value(noneRecord);
        }
    }
    final CompletableFuture<Optional<LogRecordWithDLSN>> promise = new CompletableFuture<Optional<LogRecordWithDLSN>>();
    final FutureEventListener<LogSegmentRandomAccessEntryReader> openReaderListener = new FutureEventListener<LogSegmentRandomAccessEntryReader>() {

        @Override
        public void onSuccess(final LogSegmentRandomAccessEntryReader reader) {
            promise.whenComplete((value, cause) -> reader.asyncClose());
            long lastEntryId = reader.getLastAddConfirmed();
            if (lastEntryId < 0) {
                // it means that the log segment is created but not written yet or an empty log segment.
                // it is equivalent to 'all log records whose transaction id is less than provided transactionId'
                Optional<LogRecordWithDLSN> nonRecord = Optional.absent();
                promise.complete(nonRecord);
                return;
            }
            // all log records whose transaction id is not less than provided transactionId
            if (segment.getFirstTxId() >= transactionId) {
                final FirstTxIdNotLessThanSelector selector = new FirstTxIdNotLessThanSelector(transactionId);
                asyncReadRecordFromEntries(logName, reader, segment, executorService, new SingleEntryScanContext(0L), selector).whenComplete(new FutureEventListener<LogRecordWithDLSN>() {

                    @Override
                    public void onSuccess(LogRecordWithDLSN value) {
                        promise.complete(Optional.of(selector.result()));
                    }

                    @Override
                    public void onFailure(Throwable cause) {
                        promise.completeExceptionally(cause);
                    }
                });
                return;
            }
            getLogRecordNotLessThanTxIdFromEntries(logName, segment, transactionId, executorService, reader, Lists.newArrayList(0L, lastEntryId), nWays, Optional.<LogRecordWithDLSN>absent(), promise);
        }

        @Override
        public void onFailure(final Throwable cause) {
            promise.completeExceptionally(cause);
        }
    };
    entryStore.openRandomAccessReader(segment, false).whenCompleteAsync(openReaderListener, executorService);
    return promise;
}
Also used : Optional(com.google.common.base.Optional) LogSegmentRandomAccessEntryReader(org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader) FirstTxIdNotLessThanSelector(org.apache.distributedlog.selector.FirstTxIdNotLessThanSelector) CompletableFuture(java.util.concurrent.CompletableFuture) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener)

Aggregations

CompletableFuture (java.util.concurrent.CompletableFuture)2 LogSegmentRandomAccessEntryReader (org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader)2 Optional (com.google.common.base.Optional)1 IOException (java.io.IOException)1 AsyncCallback (org.apache.bookkeeper.client.AsyncCallback)1 BookKeeper (org.apache.bookkeeper.client.BookKeeper)1 LedgerHandle (org.apache.bookkeeper.client.LedgerHandle)1 FutureEventListener (org.apache.bookkeeper.common.concurrent.FutureEventListener)1 BKTransmitException (org.apache.distributedlog.exceptions.BKTransmitException)1 FirstTxIdNotLessThanSelector (org.apache.distributedlog.selector.FirstTxIdNotLessThanSelector)1