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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0816a3caa6 Optimize ListActiveLedgersCommand (#4602)
0816a3caa6 is described below

commit 0816a3caa6f3a45be916be88f7e4f25c2262398c
Author: houxiaoyu <[email protected]>
AuthorDate: Fri May 16 19:11:35 2025 +0800

    Optimize ListActiveLedgersCommand (#4602)
    
    Optimize ListActiveLedgersCommand (#4602)
---
 .../commands/bookie/ListActiveLedgersCommand.java  |  34 +++----
 .../commands/bookie/ReadLogMetadataCommand.java    |   3 +-
 .../bookie/ListActiveLedgersCommandTest.java       | 102 +++++++++++++++++++++
 3 files changed, 118 insertions(+), 21 deletions(-)

diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
index 88c29d52b5..2fc844b48f 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
@@ -24,10 +24,8 @@ import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -135,17 +133,13 @@ public class ListActiveLedgersCommand extends 
BookieCommand<ActiveLedgerFlags>{
             if  (resultCode.get() == BKException.Code.OK) {
               DefaultEntryLogger entryLogger = new 
ReadOnlyDefaultEntryLogger(bkConf);
               EntryLogMetadata entryLogMetadata = 
entryLogger.getEntryLogMetadata(cmdFlags.logId);
-              List<Long> ledgersOnEntryLog = 
entryLogMetadata.getLedgersMap().keys();
-              if (ledgersOnEntryLog.size() == 0) {
+              Map<Long, Long> ledgersOnEntryLog = 
entryLogMetadata.getLedgersMap().asMap();
+              if (ledgersOnEntryLog.isEmpty()) {
                 LOG.info("Ledgers on log file {} is empty", cmdFlags.logId);
               }
-              List<Long> activeLedgersOnEntryLog = new 
ArrayList<Long>(ledgersOnEntryLog.size());
-              for (long ledger : ledgersOnEntryLog) {
-                if (activeLedgersOnMetadata.contains(ledger)) {
-                  activeLedgersOnEntryLog.add(ledger);
-                }
-              }
-              printActiveLedgerOnEntryLog(cmdFlags.logId, 
activeLedgersOnEntryLog);
+
+              entryLogMetadata.removeLedgerIf(ledgerId -> 
!activeLedgersOnMetadata.contains(ledgerId));
+              printActiveLedgerOnEntryLog(cmdFlags.logId, entryLogMetadata);
             } else {
               LOG.info("Read active ledgers id from metadata store,fail code 
{}", resultCode.get());
               throw BKException.create(resultCode.get());
@@ -161,15 +155,17 @@ public class ListActiveLedgersCommand extends 
BookieCommand<ActiveLedgerFlags>{
       });
     }
 
-    public void printActiveLedgerOnEntryLog(long logId, List<Long> 
activeLedgers){
-      if (activeLedgers.size() == 0){
+    private void printActiveLedgerOnEntryLog(long logId, EntryLogMetadata 
entryLogMetadata) {
+      LOG.info("Print active ledgers of entrylog {} ({}.log)", logId, 
Long.toHexString(logId));
+      if (entryLogMetadata.getRemainingSize() == 0){
         LOG.info("No active ledgers on log file {}", logId);
       } else {
-        LOG.info("Active ledgers on entry log {} as follow:", logId);
-      }
-      Collections.sort(activeLedgers);
-      for (long a : activeLedgers){
-        LOG.info("{} ", ledgerIdFormatter.formatLedgerId(a));
+        LOG.info("entryLogId: {}, remaining size: {}, total size: {}, usage: 
{}", entryLogMetadata.getEntryLogId(),
+                entryLogMetadata.getRemainingSize(), 
entryLogMetadata.getTotalSize(), entryLogMetadata.getUsage());
       }
+      entryLogMetadata.getLedgersMap().forEach((ledgerId, size) -> {
+        LOG.info("--------- Lid={}, TotalSizeOfEntriesOfLedger={}  ---------",
+                ledgerIdFormatter.formatLedgerId(ledgerId), size);
+      });
     }
 }
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
index b3a88af7e0..e39bd328c7 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
@@ -131,8 +131,7 @@ public class ReadLogMetadataCommand extends 
BookieCommand<ReadLogMetadataFlags>
         LOG.info("Print entryLogMetadata of entrylog {} ({}.log)", logId, 
Long.toHexString(logId));
         initEntryLogger(conf);
         EntryLogMetadata entryLogMetadata = 
entryLogger.getEntryLogMetadata(logId);
-        LOG.info("entryLogId: {}, remaining size: {}, total size: {}, usage: 
{}", entryLogMetadata.getEntryLogId(),
-                entryLogMetadata.getRemainingSize(), 
entryLogMetadata.getTotalSize(), entryLogMetadata.getUsage());
+        LOG.info("entryLogId: {}, total size: {}", 
entryLogMetadata.getEntryLogId(), entryLogMetadata.getTotalSize());
 
         entryLogMetadata.getLedgersMap().forEach((ledgerId, size) -> {
             LOG.info("--------- Lid={}, TotalSizeOfEntriesOfLedger={}  
---------",
diff --git 
a/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommandTest.java
 
b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommandTest.java
new file mode 100644
index 0000000000..9cf46629a0
--- /dev/null
+++ 
b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommandTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bookkeeper.tools.cli.commands.bookie;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.bookkeeper.bookie.EntryLogMetadata;
+import org.apache.bookkeeper.bookie.ReadOnlyDefaultEntryLogger;
+import org.apache.bookkeeper.client.BKException;
+import org.apache.bookkeeper.meta.LedgerManager;
+import org.apache.bookkeeper.meta.LedgerManagerFactory;
+import org.apache.bookkeeper.proto.BookkeeperInternalCallbacks;
+import org.apache.bookkeeper.tools.cli.helpers.BookieCommandTestBase;
+import org.apache.bookkeeper.util.LedgerIdFormatter;
+import org.apache.zookeeper.AsyncCallback;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link ListActiveLedgersCommand}.
+ */
+public class ListActiveLedgersCommandTest extends BookieCommandTestBase {
+    private EntryLogMetadata entryLogMetadata;
+
+    public ListActiveLedgersCommandTest() {
+        super(3, 3);
+    }
+
+    @Override
+    public void setup() throws Exception {
+        super.setup();
+
+        mockServerConfigurationConstruction();
+
+        LedgerManagerFactory mFactory = mock(LedgerManagerFactory.class);
+        mockMetadataDriversWithLedgerManagerFactory(mFactory);
+
+        mockStatic(LedgerIdFormatter.class)
+                .when(() -> LedgerIdFormatter.newLedgerIdFormatter(any()))
+                .thenReturn(new LedgerIdFormatter.LongLedgerIdFormatter());
+
+        LedgerManager ledgerManager = mock(LedgerManager.class);
+        when(mFactory.newLedgerManager()).thenReturn(ledgerManager);
+
+        doAnswer(invocation -> {
+            BookkeeperInternalCallbacks.Processor<Long> processor = 
invocation.getArgument(0);
+            AsyncCallback.VoidCallback cb = 
mock(AsyncCallback.VoidCallback.class);
+            processor.process(101L, cb); // only legerId-101 on metadata
+
+            AsyncCallback.VoidCallback callback = invocation.getArgument(1);
+            callback.processResult(BKException.Code.OK, "", null);
+            return true;
+        
}).when(ledgerManager).asyncProcessLedgers(any(BookkeeperInternalCallbacks.Processor.class),
+                any(AsyncCallback.VoidCallback.class), any(), anyInt(), 
anyInt());
+
+        entryLogMetadata = createEntryLogMeta();
+        mockConstruction(ReadOnlyDefaultEntryLogger.class, (entryLogger, 
context) ->  {
+            
when(entryLogger.getEntryLogMetadata(anyLong())).thenReturn(entryLogMetadata);
+        });
+    }
+
+    @Test
+    public void testCommand() {
+        ListActiveLedgersCommand command = new ListActiveLedgersCommand();
+        Assert.assertTrue(command.apply(bkFlags, new String[] {"-l", "0", 
"-t", "1000000"}));
+
+        EntryLogMetadata entryLogMetadataToPrint = createEntryLogMeta();
+        entryLogMetadataToPrint.removeLedgerIf(lId -> lId == 100L);
+
+        Assert.assertEquals(entryLogMetadataToPrint.getTotalSize(), 
entryLogMetadata.getTotalSize());
+        Assert.assertEquals(entryLogMetadataToPrint.getRemainingSize(), 
entryLogMetadata.getRemainingSize());
+        Assert.assertEquals(entryLogMetadataToPrint.getUsage(), 
entryLogMetadata.getUsage(), 0.0);
+    }
+
+    private EntryLogMetadata createEntryLogMeta() {
+        EntryLogMetadata entryLogMetadata = new EntryLogMetadata(0);
+        entryLogMetadata.addLedgerSize(100, 10);
+        entryLogMetadata.addLedgerSize(101, 20);
+        return entryLogMetadata;
+    }
+}

Reply via email to