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;
}
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;
}
Aggregations