aswinshakil commented on code in PR #7293:
URL: https://github.com/apache/ozone/pull/7293#discussion_r1834984660


##########
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerChecksumTreeManager.java:
##########
@@ -143,12 +147,124 @@ public void markBlocksAsDeleted(KeyValueContainerData 
data, Collection<Long> del
     }
   }
 
-  public ContainerDiff diff(KeyValueContainerData thisContainer, 
ContainerProtos.ContainerChecksumInfo otherInfo)
+  public ContainerDiff diff(KeyValueContainerData thisContainer, 
ContainerProtos.ContainerChecksumInfo peerChecksumInfo)
       throws IOException {
-    // TODO HDDS-10928 compare the checksum info of the two containers and 
return a summary.
-    //  Callers can act on this summary to repair their container replica 
using the peer's replica.
-    //  This method will use the read lock, which is unused in the current 
implementation.
-    return new ContainerDiff();
+    Preconditions.assertNotNull(thisContainer, "Container data is null");
+    Preconditions.assertNotNull(peerChecksumInfo, "Peer checksum info is 
null");
+    Optional<ContainerProtos.ContainerChecksumInfo.Builder> 
thisContainerChecksumInfoBuilder =
+        read(thisContainer);
+    if (!thisContainerChecksumInfoBuilder.isPresent()) {
+      throw new IOException("The container #" + thisContainer.getContainerID() 
+ " doesn't have container checksum");
+    }
+
+    if (thisContainer.getContainerID() != peerChecksumInfo.getContainerID()) {
+      throw new IOException("Container Id does not match");
+    }
+
+    ContainerProtos.ContainerChecksumInfo thisChecksumInfo = 
thisContainerChecksumInfoBuilder.get().build();
+
+    ContainerProtos.ContainerMerkleTree thisMerkleTree = 
thisChecksumInfo.getContainerMerkleTree();
+    ContainerProtos.ContainerMerkleTree peerMerkleTree = 
peerChecksumInfo.getContainerMerkleTree();
+
+    return compareContainerMerkleTree(thisMerkleTree, peerMerkleTree);
+  }
+
+  private ContainerDiff 
compareContainerMerkleTree(ContainerProtos.ContainerMerkleTree thisMerkleTree,
+                                                   
ContainerProtos.ContainerMerkleTree peerMerkleTree) {
+
+    ContainerDiff report = new ContainerDiff();
+    if (thisMerkleTree.getDataChecksum() == peerMerkleTree.getDataChecksum()) {
+      return new ContainerDiff();
+    }
+
+    List<ContainerProtos.BlockMerkleTree> thisBlockMerkleTreeList = 
thisMerkleTree.getBlockMerkleTreeList();
+    List<ContainerProtos.BlockMerkleTree> peerBlockMerkleTreeList = 
peerMerkleTree.getBlockMerkleTreeList();
+    // Since we are reconciling our container with a peer, We only need to go 
through the peer's block list
+    int peerIdx = 0, thisIdx = 0;
+    while (peerIdx < peerBlockMerkleTreeList.size() || thisIdx < 
thisBlockMerkleTreeList.size()) {
+      ContainerProtos.BlockMerkleTree thisBlockMerkleTree = thisIdx < 
thisBlockMerkleTreeList.size() ?
+          thisBlockMerkleTreeList.get(thisIdx) : null;
+      ContainerProtos.BlockMerkleTree peerBlockMerkleTree = peerIdx < 
peerBlockMerkleTreeList.size() ?
+          peerBlockMerkleTreeList.get(peerIdx) : null;
+
+      // We have checked all the peer blocks, So we can return the 
ContainerDiff report
+      if (peerBlockMerkleTree == null) {
+        return report;
+      }
+
+      // peerBlockMerkleTree is not null, but thisBlockMerkleTree is null. 
Means we have missing blocks.
+      if (thisBlockMerkleTree == null) {
+        report.addMissingBlock(peerBlockMerkleTree);
+        peerIdx++;
+        continue;
+      }
+
+      // BlockId matches for both thisBlockMerkleTree and peerBlockMerkleTree
+      if (thisBlockMerkleTree.getBlockID() == 
peerBlockMerkleTree.getBlockID()) {
+        if (thisBlockMerkleTree.getBlockChecksum() != 
peerBlockMerkleTree.getBlockChecksum()) {
+          compareBlockMerkleTree(report, thisBlockMerkleTree, 
peerBlockMerkleTree);
+        }
+        peerIdx++;
+        thisIdx++;
+      } else {
+        if (peerBlockMerkleTree.getBlockID() > 
thisBlockMerkleTree.getBlockID()) {
+          thisIdx++;
+        } else {
+          report.addMissingBlock(peerBlockMerkleTree);
+          peerIdx++;
+        }
+      }
+    }
+    return report;
+  }
+
+  private void compareBlockMerkleTree(ContainerDiff report, 
ContainerProtos.BlockMerkleTree thisBlockMerkleTree,
+                                      ContainerProtos.BlockMerkleTree 
peerBlockMerkleTree) {
+
+    List<ContainerProtos.ChunkMerkleTree> thisChunkMerkleTreeList = 
thisBlockMerkleTree.getChunkMerkleTreeList();
+    List<ContainerProtos.ChunkMerkleTree> peerChunkMerkleTreeList = 
peerBlockMerkleTree.getChunkMerkleTreeList();
+
+    // Since we are reconciling our container with a peer, We only need to go 
through the peer's chunk list
+    int peerIdx = 0, thisIdx = 0;
+    while (peerIdx < peerChunkMerkleTreeList.size() || thisIdx < 
thisChunkMerkleTreeList.size()) {

Review Comment:
   Updated the implementation



-- 
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