bbotella commented on code in PR #3733:
URL: https://github.com/apache/cassandra/pull/3733#discussion_r1878269268


##########
src/java/org/apache/cassandra/tools/nodetool/Status.java:
##########
@@ -179,15 +244,112 @@ private void addNode(String endpoint, Float owns, 
HostStatWithPort hostStat, int
             throw new RuntimeException(e);
         }
 
-        epDns = hostStat.ipOrDns(printPort);
         if (isTokenPerNode)
+            return List.of(addressAndPort, statusAndState, epDns, load, 
strOwns, hostID, hostStat.token, rack);
+        else
+            return List.of(addressAndPort, statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+    }
+
+    private Boolean desc()
+    {
+        if(sortOrder==sortOrder.desc)
+        {
+            return true;
+        }
+        else if(sortOrder==sortOrder.asc)
         {
-            tableBuilder.add(statusAndState, epDns, load, strOwns, hostID, 
hostStat.token, rack);
+            return false;
         }
         else
         {
-            tableBuilder.add(statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+            return null;
+        }
+    }
+
+    private Map<String, List<Object>> sort(Map<String, List<Object>> map)
+    {
+        switch (sortBy)
+        {
+            case none:
+                return map;
+            case ip:
+                return sortInternal(map, SortBy.ip, 0, desc() != null ? desc() 
: false); // default order is ascending
+            case load:
+                return sortInternal(map, SortBy.load, 3, desc() != null ? 
desc() : true); // default order is descending
+            case id:
+                return sortInternal(map, SortBy.id, isTokenPerNode ? 5 : 6, 
desc() != null ? desc() : false); // default order is ascending
+            case rack:
+                return sortInternal(map, SortBy.rack, 7, desc() != null ? 
desc() : false); // default order is ascending
+            case owns:
+                return sortInternal(map, SortBy.owns, isTokenPerNode ? 4 : 5, 
desc() != null ? desc() : true); // default order is descending
+            case status:
+                return  sortInternal(map, SortBy.status, 1, desc() != null ? 
desc() : true); // default order is descending
+            default:
+                throw new IllegalArgumentException("Sorting by " + sortBy + " 
is not supported.");
         }
     }
 
+    private LinkedHashMap<String, List<Object>> sortInternal(Map<String, 
List<Object>> data, SortBy sortBy, int index, boolean descending)
+    {
+        return data.entrySet()
+                .stream()
+                .sorted((e1, e2) -> {
+                    if (sortBy == SortBy.ip)
+                    {
+                        InetAddressAndPort addr1 = (InetAddressAndPort) 
e1.getValue().get(index);

Review Comment:
   Things like `InetAddressAndPort` already implement `Comparable`. Couldn't we 
make use of that for this sorting?



##########
src/java/org/apache/cassandra/tools/nodetool/Status.java:
##########
@@ -108,15 +156,32 @@ public void execute(NodeProbe probe)
             TableBuilder tableBuilder = sharedTable.next();
             addNodesHeader(hasEffectiveOwns, tableBuilder);
 
-            ArrayListMultimap<String, HostStatWithPort> hostToTokens = 
ArrayListMultimap.create();
+            ArrayListMultimap<InetAddressAndPort, HostStatWithPort> 
hostToTokens = ArrayListMultimap.create();
             for (HostStatWithPort stat : dc.getValue())
-                
hostToTokens.put(stat.endpointWithPort.getHostAddressAndPort(), stat);
+                hostToTokens.put(stat.endpointWithPort, stat);
 
-            for (String endpoint : hostToTokens.keySet())
+            Map<String, List<Object>> data = new HashMap<>();
+            for (InetAddressAndPort endpoint : hostToTokens.keySet())
             {
-                Float owns = ownerships.get(endpoint);
+                Float owns = ownerships.get(endpoint.getHostAddressAndPort());
                 List<HostStatWithPort> tokens = hostToTokens.get(endpoint);
-                addNode(endpoint, owns, tokens.get(0), tokens.size(), 
hasEffectiveOwns, tableBuilder);
+
+                HostStatWithPort hostStatWithPort = tokens.get(0);
+                String epDns = hostStatWithPort.ipOrDns(printPort);
+                List<Object> nodeData = addNode(epDns, endpoint, owns, 
hostStatWithPort, tokens.size(), hasEffectiveOwns);
+                data.put(epDns, nodeData);
+            }
+
+            data = sort(data);
+
+            for (Map.Entry<String, List<Object>> entry : data.entrySet())
+            {
+                List<Object> values = entry.getValue();
+                List<String> row = new ArrayList<>();
+                for (int i = 1; i < values.size(); i++)

Review Comment:
   Quick question. Why are we skipping `i = 0`?



##########
src/java/org/apache/cassandra/tools/nodetool/Status.java:
##########
@@ -179,15 +244,112 @@ private void addNode(String endpoint, Float owns, 
HostStatWithPort hostStat, int
             throw new RuntimeException(e);
         }
 
-        epDns = hostStat.ipOrDns(printPort);
         if (isTokenPerNode)
+            return List.of(addressAndPort, statusAndState, epDns, load, 
strOwns, hostID, hostStat.token, rack);
+        else
+            return List.of(addressAndPort, statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+    }
+
+    private Boolean desc()

Review Comment:
   `return sortOrder == null ? null : sortOrder == SortOrder.desc`?



##########
src/java/org/apache/cassandra/tools/nodetool/Status.java:
##########
@@ -179,15 +244,112 @@ private void addNode(String endpoint, Float owns, 
HostStatWithPort hostStat, int
             throw new RuntimeException(e);
         }
 
-        epDns = hostStat.ipOrDns(printPort);
         if (isTokenPerNode)
+            return List.of(addressAndPort, statusAndState, epDns, load, 
strOwns, hostID, hostStat.token, rack);
+        else
+            return List.of(addressAndPort, statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+    }
+
+    private Boolean desc()
+    {
+        if(sortOrder==sortOrder.desc)
+        {
+            return true;
+        }
+        else if(sortOrder==sortOrder.asc)
         {
-            tableBuilder.add(statusAndState, epDns, load, strOwns, hostID, 
hostStat.token, rack);
+            return false;
         }
         else
         {
-            tableBuilder.add(statusAndState, epDns, load, 
String.valueOf(size), strOwns, hostID, rack);
+            return null;
+        }
+    }
+
+    private Map<String, List<Object>> sort(Map<String, List<Object>> map)
+    {
+        switch (sortBy)
+        {
+            case none:
+                return map;
+            case ip:
+                return sortInternal(map, SortBy.ip, 0, desc() != null ? desc() 
: false); // default order is ascending
+            case load:
+                return sortInternal(map, SortBy.load, 3, desc() != null ? 
desc() : true); // default order is descending
+            case id:
+                return sortInternal(map, SortBy.id, isTokenPerNode ? 5 : 6, 
desc() != null ? desc() : false); // default order is ascending
+            case rack:
+                return sortInternal(map, SortBy.rack, 7, desc() != null ? 
desc() : false); // default order is ascending
+            case owns:
+                return sortInternal(map, SortBy.owns, isTokenPerNode ? 4 : 5, 
desc() != null ? desc() : true); // default order is descending
+            case status:
+                return  sortInternal(map, SortBy.status, 1, desc() != null ? 
desc() : true); // default order is descending
+            default:
+                throw new IllegalArgumentException("Sorting by " + sortBy + " 
is not supported.");
         }
     }
 
+    private LinkedHashMap<String, List<Object>> sortInternal(Map<String, 
List<Object>> data, SortBy sortBy, int index, boolean descending)

Review Comment:
   I think it'd be better and more readable to have specific sorting methods 
instead of having a big if else inside the `sortInternal` method.



##########
test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java:
##########
@@ -117,4 +117,51 @@ private void validateStatusOutput(String hostForm, 
String... args)
         assertThat(hostStatus).endsWith(SimpleSnitch.RACK_NAME);
         assertThat(hostStatus).doesNotContain("?");
     }
-}
+
+    @Test
+    public void testSortByIp() {

Review Comment:
   I think we need further testing with multiple hosts to make sure the sorting 
piece is working as expected.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to