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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0539afa0b28 HDDS-16214. Avoid per-group list copies in KeyManagerImpl 
read paths (#11078)
0539afa0b28 is described below

commit 0539afa0b28fd4394423673100a5a74ec9aa689a
Author: YANG-SYUAN CHOU <[email protected]>
AuthorDate: Tue Sep 8 12:21:52 2026 +0800

    HDDS-16214. Avoid per-group list copies in KeyManagerImpl read paths 
(#11078)
    
    Co-authored-by: sarvekshayr <[email protected]>
---
 .../org/apache/hadoop/ozone/om/KeyManagerImpl.java | 69 ++++++++++++----------
 1 file changed, 38 insertions(+), 31 deletions(-)

diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
index 99429d52ec3..d74614579e2 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
@@ -722,10 +722,13 @@ private void addBlockToken4Read(OmKeyInfo value) throws 
IOException {
     if (grpcBlockTokenEnabled) {
       String remoteUser = getRemoteUser().getShortUserName();
       for (OmKeyLocationInfoGroup key : value.getKeyLocationVersions()) {
-        key.createLocationList().forEach(k -> {
-          k.setToken(secretManager.generateToken(remoteUser, k.getBlockID(),
-              EnumSet.of(READ), k.getLength()));
-        });
+        for (List<OmKeyLocationInfo> locationInfoList :
+            key.getLocationLists()) {
+          locationInfoList.forEach(k -> {
+            k.setToken(secretManager.generateToken(remoteUser, k.getBlockID(),
+                EnumSet.of(READ), k.getLength()));
+          });
+        }
       }
     }
   }
@@ -2264,34 +2267,37 @@ private void sortDatanodes(String clientMachine, 
List<OmKeyInfo> keyInfos) {
           LOG.warn("No location for key {}", keyInfo);
           continue;
         }
-        for (OmKeyLocationInfo k : key.createLocationList()) {
-          Pipeline pipeline = k.getPipeline();
-          List<DatanodeDetails> nodes = pipeline.getNodes();
-          if (nodes.isEmpty()) {
-            LOG.warn("No datanodes in pipeline {}", pipeline.getId());
-            continue;
-          }
+        for (List<OmKeyLocationInfo> locationInfoList :
+            key.getLocationLists()) {
+          for (OmKeyLocationInfo k : locationInfoList) {
+            Pipeline pipeline = k.getPipeline();
+            List<DatanodeDetails> nodes = pipeline.getNodes();
+            if (nodes.isEmpty()) {
+              LOG.warn("No datanodes in pipeline {}", pipeline.getId());
+              continue;
+            }
 
-          final Set<String> uuidSet = 
nodes.stream().map(DatanodeDetails::getUuidString)
-              .collect(Collectors.toSet());
-
-          List<? extends DatanodeDetails> sortedNodes = 
sortedPipelines.get(uuidSet);
-          if (sortedNodes == null) {
-            sortedNodes = sortDatanodes(nodes, clientMachine);
-            // Cache only a freshly sorted order, not an input list returned
-            // unchanged when no sort happens: that order is per-pipeline and 
must
-            // not be reused for another pipeline with the same node set. The 
read
-            // sort always returns a new list, so this never skips caching 
here; it
-            // keeps the pattern identical to the write path.
-            if (sortedNodes != null && sortedNodes != nodes) {
-              sortedPipelines.put(uuidSet, sortedNodes);
+            final Set<String> uuidSet = 
nodes.stream().map(DatanodeDetails::getUuidString)
+                .collect(Collectors.toSet());
+
+            List<? extends DatanodeDetails> sortedNodes = 
sortedPipelines.get(uuidSet);
+            if (sortedNodes == null) {
+              sortedNodes = sortDatanodes(nodes, clientMachine);
+              // Cache only a freshly sorted order, not an input list returned
+              // unchanged when no sort happens: that order is per-pipeline 
and must
+              // not be reused for another pipeline with the same node set. 
The read
+              // sort always returns a new list, so this never skips caching 
here; it
+              // keeps the pattern identical to the write path.
+              if (sortedNodes != null && sortedNodes != nodes) {
+                sortedPipelines.put(uuidSet, sortedNodes);
+              }
+            } else if (LOG.isDebugEnabled()) {
+              LOG.debug("Found sorted datanodes for pipeline {} and client {} "
+                  + "in cache", pipeline.getId(), clientMachine);
+            }
+            if (!Objects.equals(pipeline.getNodesInOrder(), sortedNodes)) {
+              k.setPipeline(pipeline.copyWithNodesInOrder(sortedNodes));
             }
-          } else if (LOG.isDebugEnabled()) {
-            LOG.debug("Found sorted datanodes for pipeline {} and client {} "
-                + "in cache", pipeline.getId(), clientMachine);
-          }
-          if (!Objects.equals(pipeline.getNodesInOrder(), sortedNodes)) {
-            k.setPipeline(pipeline.copyWithNodesInOrder(sortedNodes));
           }
         }
       }
@@ -2570,7 +2576,8 @@ private void setUpdatedContainerLocation(OmKeyInfo 
keyInfo,
   @Nonnull
   private Stream<Long> extractContainerIDs(OmKeyInfo keyInfo) {
     return keyInfo.getKeyLocationVersions().stream()
-        .flatMap(v -> v.createLocationList().stream())
+        .flatMap(v -> v.getLocationLists().stream())
+        .flatMap(List::stream)
         .map(BlockLocationInfo::getContainerID);
   }
 }


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

Reply via email to