private void internalReadFromLedger(LedgerHandle ledger, OpReadEntry opReadEntry) { // Perform the read long firstEntry = opReadEntry.readPosition.getEntryId(); if (firstEntry > ledger.getLastAddConfirmed()) { log.debug( "[{}] No more messages to read from ledger={} lastEntry={} readEntry={}", va(name, ledger.getId(), ledger.getLastAddConfirmed(), firstEntry)); if (ledger.getId() != currentLedger.getId()) { // Cursor was placed past the end of one ledger, move it to the // beginning of the next ledger Long nextLedgerId = ledgers.ceilingKey(ledger.getId() + 1); opReadEntry.nextReadPosition = new Position(nextLedgerId, 0); } opReadEntry.emptyResponse(); return; } long lastEntry = min(firstEntry + opReadEntry.count - 1, ledger.getLastAddConfirmed()); long expectedEntries = lastEntry - firstEntry + 1; opReadEntry.entries = Lists.newArrayListWithExpectedSize((int) expectedEntries); log.debug( "[{}] Reading entries from ledger {} - first={} last={}", va(name, ledger.getId(), firstEntry, lastEntry)); ledger.asyncReadEntries(firstEntry, lastEntry, this, opReadEntry); }
/* * (non-Javadoc) * * @see * org.apache.bookkeeper.client.AsyncCallback.OpenCallback#openComplete(int, * org.apache.bookkeeper.client.LedgerHandle, java.lang.Object) */ @Override public void openComplete(int rc, LedgerHandle ledger, Object ctx) { OpReadEntry opReadEntry = (OpReadEntry) ctx; if (rc != BKException.Code.OK) { opReadEntry.failed(new ManagedLedgerException(BKException.create(rc))); return; } log.debug("[{}] Successfully opened ledger {} for reading", name, ledger.getId()); internalReadFromLedger(ledger, opReadEntry); }
protected synchronized void asyncReadEntries(OpReadEntry opReadEntry) { if (state == State.Fenced) { opReadEntry.failed(new ManagedLedgerFencedException()); return; } LedgerHandle ledger = null; if (opReadEntry.readPosition.getLedgerId() == -1) { if (ledgers.isEmpty()) { // The ManagedLedger is completely empty opReadEntry.emptyResponse(); return; } // Initialize the position on the first entry for the first ledger // in the set opReadEntry.readPosition = new Position(ledgers.firstKey(), 0); } long id = opReadEntry.readPosition.getLedgerId(); if (id == currentLedger.getId()) { // Current writing ledger is not in the cache (since we don't want // it to be automatically evicted), and we cannot use 2 different // ledger handles (read & write)for the same ledger. ledger = currentLedger; } else { ledger = ledgerCache.getIfPresent(id); if (ledger == null) { // Open the ledger and cache the handle log.debug("[{}] Asynchronously opening ledger {} for read", name, id); bookKeeper.asyncOpenLedger( id, config.getDigestType(), config.getPassword(), this, opReadEntry); return; } } internalReadFromLedger(ledger, opReadEntry); }
/* * (non-Javadoc) * * @see * org.apache.bookkeeper.client.AsyncCallback.ReadCallback#readComplete(int, * org.apache.bookkeeper.client.LedgerHandle, java.util.Enumeration, * java.lang.Object) */ @Override public void readComplete( int rc, LedgerHandle lh, Enumeration<LedgerEntry> entriesEnum, Object ctx) { OpReadEntry opReadEntry = (OpReadEntry) ctx; if (rc != BKException.Code.OK) { log.warn( "[{}] read failed from ledger {} at position:{}", va(name, lh.getId(), opReadEntry.readPosition)); opReadEntry.failed(new ManagedLedgerException(BKException.create(rc))); return; } List<Entry> entries = opReadEntry.entries; while (entriesEnum.hasMoreElements()) entries.add(new EntryImpl(entriesEnum.nextElement())); long lastEntry = entries.get(entries.size() - 1).getPosition().getEntryId(); // Get the "next read position", we need to advance the position taking // care of ledgers boundaries Position nextReadPosition; if (lastEntry < lh.getLastAddConfirmed()) { nextReadPosition = new Position(lh.getId(), lastEntry + 1); } else { // Move to next ledger Long nextLedgerId = ledgers.ceilingKey(lh.getId() + 1); if (nextLedgerId == null) { // We are already in the last ledger nextReadPosition = new Position(lh.getId(), lastEntry + 1); } else { nextReadPosition = new Position(nextLedgerId, 0); } } opReadEntry.nextReadPosition = nextReadPosition; opReadEntry.succeeded(); }