You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by si...@apache.org on 2018/12/10 06:54:49 UTC

[pulsar] branch master updated: In managed ledger ReadOnlyCursor, optimize for when there's a new ledger created (#3148)

This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 20fbb5d  In managed ledger ReadOnlyCursor, optimize for when there's a new ledger created (#3148)
20fbb5d is described below

commit 20fbb5d7aee9f05afd55d02b37ef74acf22cae42
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Sun Dec 9 22:54:44 2018 -0800

    In managed ledger ReadOnlyCursor, optimize for when there's a new ledger created (#3148)
    
    ### Motivation
    
    In managed ledger, the check `Cursor.hasMoreEntries()` is very cheap when the last ledger has at least some entries (eg: just longs comparison). If it's empty, we need to do a more expensive check that involve looking at the ledgers list to make sure the answer is always correct.
    
    When creating a read-only cursor, we get a snapshot of the current state. If the topic was left with a new ledger created and no entry into that, the `hasMoreEntries()` will be always expensive.
    
    To avoid that, if the last ledger is empty, initialize the last written position on the last entry of previous ledger.
---
 .../mledger/impl/ReadOnlyManagedLedgerImpl.java         | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ReadOnlyManagedLedgerImpl.java b/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ReadOnlyManagedLedgerImpl.java
index 052aa0e..4f630ee 100644
--- a/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ReadOnlyManagedLedgerImpl.java
+++ b/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ReadOnlyManagedLedgerImpl.java
@@ -121,8 +121,21 @@ public class ReadOnlyManagedLedgerImpl extends ManagedLedgerImpl {
     }
 
     private ReadOnlyCursor createReadOnlyCursor(PositionImpl startPosition) {
-        lastConfirmedEntry = ledgers.size() == 0 ? PositionImpl.earliest
-                : new PositionImpl(ledgers.lastKey(), ledgers.lastEntry().getValue().getEntries() - 1);
+        if (ledgers.isEmpty()) {
+            lastConfirmedEntry = PositionImpl.earliest;
+        } else if (ledgers.lastEntry().getValue().getEntries() > 0) {
+            // Last ledger has some of the entries
+            lastConfirmedEntry = new PositionImpl(ledgers.lastKey(), ledgers.lastEntry().getValue().getEntries() - 1);
+        } else {
+            // Last ledger is empty. If there is a previous ledger, position on the last entry of that ledger
+            if (ledgers.size() > 1) {
+                long lastLedgerId = ledgers.lastKey();
+                LedgerInfo li = ledgers.headMap(lastLedgerId, false).lastEntry().getValue();
+                lastConfirmedEntry = new PositionImpl(li.getLedgerId(), li.getEntries() - 1);
+            } else {
+                lastConfirmedEntry = PositionImpl.earliest;
+            }
+        }
 
         ReadOnlyCursorImpl cursor = new ReadOnlyCursorImpl(bookKeeper, config, this, startPosition, "read-only-cursor");
         return cursor;