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

clohfink pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 893908e  Nodetool status Load columns has wrong width
893908e is described below

commit 893908e2dc1fe011e38c847395cb39be4ca53d89
Author: Chris Lohfink <[email protected]>
AuthorDate: Mon Jul 22 18:15:37 2019 -0500

    Nodetool status Load columns has wrong width
    
    Patch by Kirk True; Reviewed by Chris Lohfink for CASSANDRA-14787
---
 CHANGES.txt                                        |  1 +
 .../apache/cassandra/tools/nodetool/Status.java    | 96 ++++++----------------
 .../tools/nodetool/formatter/TableBuilder.java     |  9 +-
 3 files changed, 35 insertions(+), 71 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index bc781d6..f9c0306 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.0
+ * Align load column in nodetool status output (CASSANDRA-14787)
  * CassandraNetworkAuthorizer uses cached roles info (CASSANDRA-15089)
  * Introduce optional timeouts for idle client sessions (CASSANDRA-11097)
  * Fix AlterTableStatement dropped type validation order (CASSANDRA-15203)
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Status.java 
b/src/java/org/apache/cassandra/tools/nodetool/Status.java
index 21868e7..8c37022 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/Status.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/Status.java
@@ -25,18 +25,16 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.text.DecimalFormat;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.SortedMap;
-import java.util.function.ToIntFunction;
 
 import org.apache.cassandra.locator.EndpointSnitchInfoMBean;
 import org.apache.cassandra.locator.InetAddressAndPort;
 import org.apache.cassandra.tools.NodeProbe;
 import org.apache.cassandra.tools.NodeTool;
 import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+import org.apache.cassandra.tools.nodetool.formatter.TableBuilder;
 
 import com.google.common.collect.ArrayListMultimap;
 
@@ -51,7 +49,6 @@ public class Status extends NodeToolCmd
     private boolean resolveIp = false;
 
     private boolean isTokenPerNode = true;
-    private String format = null;
     private Collection<String> joiningNodes, leavingNodes, movingNodes, 
liveNodes, unreachableNodes;
     private Map<String, String> loadMap, hostIDMap;
     private EndpointSnitchInfoMBean epSnitchInfo;
@@ -70,6 +67,7 @@ public class Status extends NodeToolCmd
         epSnitchInfo = probe.getEndpointSnitchInfoProxy();
 
         StringBuilder errors = new StringBuilder();
+        TableBuilder tableBuilder = new TableBuilder("  ");
 
         if (printPort)
         {
@@ -97,8 +95,6 @@ public class Status extends NodeToolCmd
             if (dcs.size() < tokensToEndpoints.size())
                 isTokenPerNode = false;
 
-            int maxAddressLength = findMaxAddressLength(dcs, s -> 
s.ipOrDns().length());
-
             // Datacenters
             for (Map.Entry<String, SetHostStatWithPort> dc : dcs.entrySet())
             {
@@ -111,7 +107,7 @@ public class Status extends NodeToolCmd
                 System.out.println("Status=Up/Down");
                 System.out.println("|/ State=Normal/Leaving/Joining/Moving");
 
-                printNodesHeader(hasEffectiveOwns, isTokenPerNode, 
maxAddressLength);
+                addNodesHeader(hasEffectiveOwns, tableBuilder);
 
                 ArrayListMultimap<InetAddressAndPort, HostStatWithPort> 
hostToTokens = ArrayListMultimap.create();
                 for (HostStatWithPort stat : dc.getValue())
@@ -121,10 +117,11 @@ public class Status extends NodeToolCmd
                 {
                     Float owns = ownerships.get(endpoint.toString());
                     List<HostStatWithPort> tokens = hostToTokens.get(endpoint);
-                    printNodeWithPort(endpoint.toString(), owns, tokens, 
hasEffectiveOwns, isTokenPerNode, maxAddressLength);
+                    addNodeWithPort(endpoint.toString(), owns, tokens, 
hasEffectiveOwns, tableBuilder);
                 }
             }
 
+            tableBuilder.printTo(System.out);
             System.out.printf("%n" + errors);
         }
         else
@@ -153,8 +150,6 @@ public class Status extends NodeToolCmd
             if (dcs.values().size() < tokensToEndpoints.keySet().size())
                 isTokenPerNode = false;
 
-            int maxAddressLength = findMaxAddressLength(dcs, s -> 
s.ipOrDns().length());
-
             // Datacenters
             for (Map.Entry<String, SetHostStat> dc : dcs.entrySet())
             {
@@ -167,7 +162,7 @@ public class Status extends NodeToolCmd
                 System.out.println("Status=Up/Down");
                 System.out.println("|/ State=Normal/Leaving/Joining/Moving");
 
-                printNodesHeader(hasEffectiveOwns, isTokenPerNode, 
maxAddressLength);
+                addNodesHeader(hasEffectiveOwns, tableBuilder);
 
                 ArrayListMultimap<InetAddress, HostStat> hostToTokens = 
ArrayListMultimap.create();
                 for (HostStat stat : dc.getValue())
@@ -177,43 +172,29 @@ public class Status extends NodeToolCmd
                 {
                     Float owns = ownerships.get(endpoint);
                     List<HostStat> tokens = hostToTokens.get(endpoint);
-                    printNode(endpoint.getHostAddress(), owns, tokens, 
hasEffectiveOwns, isTokenPerNode, maxAddressLength);
+                    addNode(endpoint.getHostAddress(), owns, tokens, 
hasEffectiveOwns, tableBuilder);
                 }
             }
 
+            tableBuilder.printTo(System.out);
             System.out.printf("%n" + errors);
         }
     }
 
-    private <T extends Iterable<U>, U> int findMaxAddressLength(Map<String, T> 
dcs, ToIntFunction<U> computeLength)
+    private void addNodesHeader(boolean hasEffectiveOwns, TableBuilder 
tableBuilder)
     {
-        int maxAddressLength = 0;
-
-        Set<U> seenHosts = new HashSet<>();
-        for (T stats : dcs.values())
-            for (U stat : stats)
-                if (seenHosts.add(stat))
-                    maxAddressLength = Math.max(maxAddressLength, 
computeLength.applyAsInt(stat));
-
-        return maxAddressLength;
-    }
-
-    private void printNodesHeader(boolean hasEffectiveOwns, boolean 
isTokenPerNode, int maxAddressLength)
-    {
-        String fmt = getFormat(hasEffectiveOwns, isTokenPerNode, 
maxAddressLength);
         String owns = hasEffectiveOwns ? "Owns (effective)" : "Owns";
 
         if (isTokenPerNode)
-            System.out.printf(fmt, "-", "-", "Address", "Load", owns, "Host 
ID", "Token", "Rack");
+            tableBuilder.add("--", "Address", "Load", owns, "Host ID", 
"Token", "Rack");
         else
-            System.out.printf(fmt, "-", "-", "Address", "Load", "Tokens", 
owns, "Host ID", "Rack");
+            tableBuilder.add("--", "Address", "Load", "Tokens", owns, "Host 
ID", "Rack");
     }
 
-    private void printNode(String endpoint, Float owns, String epDns, String 
token, int size, boolean hasEffectiveOwns,
-                           boolean isTokenPerNode, int maxAddressLength)
+    private void addNode(String endpoint, Float owns, String epDns, String 
token, int size, boolean hasEffectiveOwns,
+                           TableBuilder tableBuilder)
     {
-        String status, state, load, strOwns, hostID, rack, fmt;
-        fmt = getFormat(hasEffectiveOwns, isTokenPerNode, maxAddressLength);
+        String status, state, load, strOwns, hostID, rack;
         if (liveNodes.contains(endpoint)) status = "U";
         else if (unreachableNodes.contains(endpoint)) status = "D";
         else status = "?";
@@ -222,6 +203,7 @@ public class Status extends NodeToolCmd
         else if (movingNodes.contains(endpoint)) state = "M";
         else state = "N";
 
+        String statusAndState = status.concat(state);
         load = loadMap.getOrDefault(endpoint, "?");
         strOwns = owns != null && hasEffectiveOwns ? new 
DecimalFormat("##0.0%").format(owns) : "?";
         hostID = hostIDMap.get(endpoint);
@@ -235,48 +217,24 @@ public class Status extends NodeToolCmd
         }
 
         if (isTokenPerNode)
-            System.out.printf(fmt, status, state, epDns, load, strOwns, 
hostID, token, rack);
+        {
+            tableBuilder.add(statusAndState, epDns, load, strOwns, hostID, 
token, rack);
+        }
         else
-            System.out.printf(fmt, status, state, epDns, load, size, strOwns, 
hostID, rack);
-    }
-
-    private void printNode(String endpoint, Float owns, List<HostStat> tokens, 
boolean hasEffectiveOwns,
-                           boolean isTokenPerNode, int maxAddressLength)
-    {
-        printNode(endpoint, owns, tokens.get(0).ipOrDns(), 
tokens.get(0).token, tokens.size(), hasEffectiveOwns,
-                  isTokenPerNode, maxAddressLength);
+        {
+            tableBuilder.add(statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+        }
     }
 
-    private void printNodeWithPort(String endpoint, Float owns, 
List<HostStatWithPort> tokens, boolean hasEffectiveOwns,
-                                   boolean isTokenPerNode, int 
maxAddressLength)
+    private void addNode(String endpoint, Float owns, List<HostStat> tokens, 
boolean hasEffectiveOwns,
+                         TableBuilder tableBuilder)
     {
-        printNode(endpoint, owns, tokens.get(0).ipOrDns(), 
tokens.get(0).token, tokens.size(), hasEffectiveOwns,
-                  isTokenPerNode, maxAddressLength);
+        addNode(endpoint, owns, tokens.get(0).ipOrDns(), tokens.get(0).token, 
tokens.size(), hasEffectiveOwns, tableBuilder);
     }
 
-    private String getFormat(boolean hasEffectiveOwns, boolean isTokenPerNode, 
int maxAddressLength)
+    private void addNodeWithPort(String endpoint, Float owns, 
List<HostStatWithPort> tokens, boolean hasEffectiveOwns,
+                                 TableBuilder tableBuilder)
     {
-        if (format == null)
-        {
-            StringBuilder buf = new StringBuilder();
-            String addressPlaceholder = String.format("%%-%ds  ", 
maxAddressLength);
-            buf.append("%s%s  ");                         // status
-            buf.append(addressPlaceholder);               // address
-            buf.append("%-9s  ");                         // load
-            if (!isTokenPerNode)
-                buf.append("%-11s  ");                     // "Tokens"
-            if (hasEffectiveOwns)
-                buf.append("%-16s  ");                    // "Owns (effective)"
-            else
-                buf.append("%-6s  ");                     // "Owns
-            buf.append("%-36s  ");                        // Host ID
-            if (isTokenPerNode)
-                buf.append("%-39s  ");                    // token
-            buf.append("%s%n");                           // "Rack"
-
-            format = buf.toString();
-        }
-
-        return format;
+        addNode(endpoint, owns, tokens.get(0).ipOrDns(), tokens.get(0).token, 
tokens.size(), hasEffectiveOwns, tableBuilder);
     }
 }
diff --git 
a/src/java/org/apache/cassandra/tools/nodetool/formatter/TableBuilder.java 
b/src/java/org/apache/cassandra/tools/nodetool/formatter/TableBuilder.java
index a56e52e..bf06d99 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/formatter/TableBuilder.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/formatter/TableBuilder.java
@@ -41,8 +41,8 @@ import javax.annotation.Nonnull;
  */
 public class TableBuilder
 {
-    // column delimiter char
-    private final char columnDelimiter;
+    // column delimiter
+    private final String columnDelimiter;
 
     private int[] maximumColumnWidth;
     private final List<String[]> rows = new ArrayList<>();
@@ -54,6 +54,11 @@ public class TableBuilder
 
     public TableBuilder(char columnDelimiter)
     {
+        this(String.valueOf(columnDelimiter));
+    }
+
+    public TableBuilder(String columnDelimiter)
+    {
         this.columnDelimiter = columnDelimiter;
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to