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

hemant 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 e03e9f39f7 HDDS-8904. Fix Snapdiff output for key renames (#5177)
e03e9f39f7 is described below

commit e03e9f39f7cb08f81c4ccf4abab8e068a8e56e62
Author: Swaminathan Balachandran <[email protected]>
AuthorDate: Thu Aug 31 10:23:11 2023 -0700

    HDDS-8904. Fix Snapdiff output for key renames (#5177)
---
 .../apache/hadoop/hdds/utils/db/BooleanCodec.java  |  74 ++++++++++
 .../apache/hadoop/hdds/utils/db/CodecBuffer.java   |  11 ++
 .../apache/hadoop/hdds/utils/db/CodecRegistry.java |   3 +-
 .../org/apache/hadoop/ozone/om/TestOmSnapshot.java |   2 +-
 .../apache/hadoop/ozone/om/OmSnapshotManager.java  |   2 -
 .../ozone/om/snapshot/SnapshotDiffManager.java     |  99 +++++--------
 .../ozone/om/snapshot/SnapshotDiffObject.java      | 164 ---------------------
 .../ozone/om/snapshot/TestSnapshotDiffManager.java | 154 ++++++++++---------
 8 files changed, 209 insertions(+), 300 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/BooleanCodec.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/BooleanCodec.java
new file mode 100644
index 0000000000..dc1090e5b8
--- /dev/null
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/BooleanCodec.java
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdds.utils.db;
+
+import javax.annotation.Nonnull;
+import java.util.function.IntFunction;
+
+/**
+ * Codec to serialize/deserialize {@link Boolean}.
+ */
+public final class BooleanCodec implements Codec<Boolean> {
+
+  private static final byte TRUE = 1;
+  private static final byte FALSE = 0;
+  private static final BooleanCodec INSTANCE = new BooleanCodec();
+
+  public static BooleanCodec get() {
+    return INSTANCE;
+  }
+
+  private BooleanCodec() {
+    // singleton
+  }
+
+  @Override
+  public boolean supportCodecBuffer() {
+    return true;
+  }
+
+  @Override
+  public CodecBuffer toCodecBuffer(Boolean object,
+      IntFunction<CodecBuffer> allocator) {
+    return allocator.apply(1).put(TRUE);
+  }
+
+  @Override
+  public Boolean fromCodecBuffer(@Nonnull CodecBuffer buffer) {
+    return buffer.asReadOnlyByteBuffer().get() == 1;
+  }
+
+  @Override
+  public byte[] toPersistedFormat(Boolean object) {
+    return object ? new byte[]{TRUE} : new byte[]{FALSE};
+  }
+
+  @Override
+  public Boolean fromPersistedFormat(byte[] rawData) {
+    if (rawData.length != 1) {
+      throw new IllegalStateException("Byte Buffer for boolean should be of " +
+          "length 1 but provided byte array of length " + rawData.length);
+    }
+    return rawData[0] == 1;
+  }
+
+  @Override
+  public Boolean copyObject(Boolean object) {
+    return object;
+  }
+}
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/CodecBuffer.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/CodecBuffer.java
index 8254022a30..6a404c3e75 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/CodecBuffer.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/utils/db/CodecBuffer.java
@@ -289,6 +289,17 @@ public final class CodecBuffer implements AutoCloseable {
     return this;
   }
 
+  /**
+   * Similar to {@link ByteBuffer#put(byte)}.
+   *
+   * @return this object.
+   */
+  public CodecBuffer put(byte val) {
+    assertRefCnt(1);
+    buf.writeByte(val);
+    return this;
+  }
+
   /**
    * Similar to {@link ByteBuffer#put(byte[])}.
    *
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/CodecRegistry.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/CodecRegistry.java
index 34e1d1c8fa..5e767537d4 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/CodecRegistry.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/CodecRegistry.java
@@ -52,7 +52,8 @@ public final class CodecRegistry {
         .addCodec(String.class, StringCodec.get())
         .addCodec(Long.class, LongCodec.get())
         .addCodec(Integer.class, IntegerCodec.get())
-        .addCodec(byte[].class, ByteArrayCodec.get());
+        .addCodec(byte[].class, ByteArrayCodec.get())
+        .addCodec(Boolean.class, BooleanCodec.get());
   }
 
   private static final class CodecMap {
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
index e592c17262..dea28e03d8 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
@@ -987,7 +987,7 @@ public class TestOmSnapshot {
         key1);
     Assert.assertEquals(diff.getDiffList(), Arrays.asList(
         SnapshotDiffReportOzone.getDiffReportEntry(
-            SnapshotDiffReport.DiffType.MODIFY, key1)));
+            SnapshotDiffReport.DiffType.RENAME, key1, key1)));
   }
 
   /**
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
index 7465319888..1bcaefccfc 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
@@ -57,7 +57,6 @@ import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.service.SnapshotDiffCleanupService;
-import org.apache.hadoop.ozone.om.snapshot.SnapshotDiffObject;
 import org.apache.hadoop.ozone.om.helpers.SnapshotDiffJob;
 import org.apache.hadoop.ozone.om.snapshot.ReferenceCounted;
 import org.apache.hadoop.ozone.om.snapshot.SnapshotCache;
@@ -392,7 +391,6 @@ public final class OmSnapshotManager implements 
AutoCloseable {
     registry.addCodec(SnapshotDiffReportOzone.DiffReportEntry.class,
         SnapshotDiffReportOzone.getDiffReportEntryCodec());
     registry.addCodec(SnapshotDiffJob.class, SnapshotDiffJob.getCodec());
-    registry.addCodec(SnapshotDiffObject.class, SnapshotDiffObject.getCodec());
     return registry.build();
   }
 
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
index 7ed8fa46e8..b8299541f0 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
@@ -51,7 +51,6 @@ import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.helpers.WithObjectID;
 import org.apache.hadoop.ozone.om.helpers.WithParentObjectId;
 import org.apache.hadoop.ozone.om.service.SnapshotDeletingService;
-import 
org.apache.hadoop.ozone.om.snapshot.SnapshotDiffObject.SnapshotDiffObjectBuilder;
 import org.apache.hadoop.ozone.snapshot.CancelSnapshotDiffResponse;
 import org.apache.hadoop.ozone.snapshot.SnapshotDiffReportOzone;
 import org.apache.hadoop.ozone.snapshot.SnapshotDiffResponse;
@@ -894,9 +893,9 @@ public class SnapshotDiffManager implements AutoCloseable {
           new RocksDbPersistentMap<>(db, toSnapshotColumnFamily, codecRegistry,
               byte[].class, byte[].class);
       // Set of unique objectId between fromSnapshot and toSnapshot.
-      final PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject =
+      final PersistentMap<byte[], Boolean> objectIdToIsDirMap =
           new RocksDbPersistentMap<>(db, objectIDsColumnFamily, codecRegistry,
-              byte[].class, SnapshotDiffObject.class);
+              byte[].class, Boolean.class);
 
       final BucketLayout bucketLayout = getBucketLayout(volumeName, bucketName,
           fromSnapshot.getMetadataManager());
@@ -950,7 +949,7 @@ public class SnapshotDiffManager implements AutoCloseable {
                 fromSnapshot, toSnapshot, fsInfo, tsInfo, useFullDiff,
                 performNonNativeDiff, tablePrefixes,
                 objectIdToKeyNameMapForFromSnapshot,
-                objectIdToKeyNameMapForToSnapshot, objectIdToDiffObject,
+                objectIdToKeyNameMapForToSnapshot, objectIdToIsDirMap,
                 oldParentIds, newParentIds, path.toString());
             return null;
           },
@@ -960,7 +959,7 @@ public class SnapshotDiffManager implements AutoCloseable {
                   fromSnapshot, toSnapshot, fsInfo, tsInfo, useFullDiff,
                   performNonNativeDiff, tablePrefixes,
                   objectIdToKeyNameMapForFromSnapshot,
-                  objectIdToKeyNameMapForToSnapshot, objectIdToDiffObject,
+                  objectIdToKeyNameMapForToSnapshot, objectIdToIsDirMap,
                   oldParentIds, newParentIds, path.toString());
             }
             return null;
@@ -989,13 +988,13 @@ public class SnapshotDiffManager implements AutoCloseable 
{
                 tsKeyTable,
                 fsDirTable,
                 tsDirTable,
-                objectIdToDiffObject,
+                objectIdToIsDirMap,
                 objectIdToKeyNameMapForFromSnapshot,
                 objectIdToKeyNameMapForToSnapshot,
                 volumeName, bucketName,
                 fromSnapshotName, toSnapshotName,
                 bucketLayout.isFileSystemOptimized(), oldParentIdPathMap,
-                newParentIdPathMap);
+                newParentIdPathMap, tablePrefixes);
             // If job is cancelled, totalDiffEntries will be equal to -1.
             if (totalDiffEntries >= 0 &&
                 areDiffJobAndSnapshotsActive(volumeName, bucketName,
@@ -1057,7 +1056,7 @@ public class SnapshotDiffManager implements AutoCloseable 
{
       final Map<String, String> tablePrefixes,
       final PersistentMap<byte[], byte[]> oldObjIdToKeyMap,
       final PersistentMap<byte[], byte[]> newObjIdToKeyMap,
-      final PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject,
+      final PersistentMap<byte[], Boolean> objectIdToIsDirMap,
       final Optional<Set<Long>> oldParentIds,
       final Optional<Set<Long>> newParentIds,
       final String diffDir) throws IOException, RocksDBException {
@@ -1082,7 +1081,7 @@ public class SnapshotDiffManager implements AutoCloseable 
{
           !skipNativeDiff && sstDumpTool.isPresent(),
           oldObjIdToKeyMap,
           newObjIdToKeyMap,
-          objectIdToDiffObject,
+          objectIdToIsDirMap,
           oldParentIds,
           newParentIds,
           tablePrefixes);
@@ -1100,7 +1099,7 @@ public class SnapshotDiffManager implements AutoCloseable 
{
             false,
             oldObjIdToKeyMap,
             newObjIdToKeyMap,
-            objectIdToDiffObject,
+            objectIdToIsDirMap,
             oldParentIds,
             newParentIds,
             tablePrefixes);
@@ -1117,7 +1116,7 @@ public class SnapshotDiffManager implements AutoCloseable 
{
       Set<String> deltaFiles, boolean nativeRocksToolsLoaded,
       PersistentMap<byte[], byte[]> oldObjIdToKeyMap,
       PersistentMap<byte[], byte[]> newObjIdToKeyMap,
-      PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject,
+      PersistentMap<byte[], Boolean> objectIdToIsDirMap,
       Optional<Set<Long>> oldParentIds,
       Optional<Set<Long>> newParentIds,
       Map<String, String> tablePrefixes) throws IOException,
@@ -1154,10 +1153,7 @@ public class SnapshotDiffManager implements 
AutoCloseable {
             byte[] rawValue = codecRegistry.asRawData(
                 key.substring(tablePrefix.length()));
             oldObjIdToKeyMap.put(rawObjId, rawValue);
-            SnapshotDiffObject diffObject =
-                createDiffObjectWithOldName(fromObjectId.getObjectID(), key,
-                    objectIdToDiffObject.get(rawObjId), isDirectoryTable);
-            objectIdToDiffObject.put(rawObjId, diffObject);
+            objectIdToIsDirMap.put(rawObjId, isDirectoryTable);
             oldParentIds.ifPresent(set -> set.add(
                 fromObjectId.getParentObjectID()));
           }
@@ -1166,10 +1162,7 @@ public class SnapshotDiffManager implements 
AutoCloseable {
             byte[] rawValue = codecRegistry.asRawData(
                 key.substring(tablePrefix.length()));
             newObjIdToKeyMap.put(rawObjId, rawValue);
-            SnapshotDiffObject diffObject =
-                createDiffObjectWithNewName(toObjectId.getObjectID(), key,
-                    objectIdToDiffObject.get(rawObjId), isDirectoryTable);
-            objectIdToDiffObject.put(rawObjId, diffObject);
+            objectIdToIsDirMap.put(rawObjId, isDirectoryTable);
             newParentIds.ifPresent(set -> set.add(toObjectId
                 .getParentObjectID()));
           }
@@ -1184,29 +1177,6 @@ public class SnapshotDiffManager implements 
AutoCloseable {
     }
   }
 
-  private SnapshotDiffObject createDiffObjectWithOldName(
-      long objectId, String oldName, SnapshotDiffObject diffObject,
-      boolean isDirectory) {
-    SnapshotDiffObjectBuilder builder = new SnapshotDiffObjectBuilder(objectId)
-        .withOldKeyName(oldName).setIsDirectory(isDirectory);
-    if (diffObject != null) {
-      builder.withNewKeyName(diffObject.getNewKeyName());
-    }
-    return builder.build();
-  }
-
-  private SnapshotDiffObject createDiffObjectWithNewName(
-      long objectId, String newName, SnapshotDiffObject diffObject,
-      boolean isDirectory) {
-
-    SnapshotDiffObjectBuilder builder = new SnapshotDiffObjectBuilder(objectId)
-        .withNewKeyName(newName).setIsDirectory(isDirectory);
-    if (diffObject != null) {
-      builder.withOldKeyName(diffObject.getOldKeyName());
-    }
-    return builder.build();
-  }
-
   @VisibleForTesting
   @SuppressWarnings("checkstyle:ParameterNumber")
   Set<String> getDeltaFiles(OmSnapshot fromSnapshot,
@@ -1311,7 +1281,7 @@ public class SnapshotDiffManager implements AutoCloseable 
{
       final Table<String, OmKeyInfo> tsTable,
       final Table<String, OmDirectoryInfo> fsDirTable,
       final Table<String, OmDirectoryInfo> tsDirTable,
-      final PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject,
+      final PersistentMap<byte[], Boolean> objectIdToIsDirMap,
       final PersistentMap<byte[], byte[]> oldObjIdToKeyMap,
       final PersistentMap<byte[], byte[]> newObjIdToKeyMap,
       final String volumeName,
@@ -1320,7 +1290,8 @@ public class SnapshotDiffManager implements AutoCloseable 
{
       final String toSnapshotName,
       final boolean isFSOBucket,
       final Optional<Map<Long, Path>> oldParentIdPathMap,
-      final Optional<Map<Long, Path>> newParentIdPathMap) {
+      final Optional<Map<Long, Path>> newParentIdPathMap,
+      final Map<String, String> tablePrefix) {
     LOG.info("Starting diff report generation for jobId: {}.", jobId);
     ColumnFamilyHandle deleteDiffColumnFamily = null;
     ColumnFamilyHandle renameDiffColumnFamily = null;
@@ -1349,8 +1320,8 @@ public class SnapshotDiffManager implements AutoCloseable 
{
       final PersistentList<byte[]> modifyDiffs =
           createDiffReportPersistentList(modifyDiffColumnFamily);
 
-      try (ClosableIterator<Map.Entry<byte[], SnapshotDiffObject>>
-               iterator = objectIdToDiffObject.iterator()) {
+      try (ClosableIterator<Map.Entry<byte[], Boolean>>
+               iterator = objectIdToIsDirMap.iterator()) {
         // This counter is used, so that we can check every 100 elements
         // if the job is cancelled and snapshots are still active.
         int counter = 0;
@@ -1361,9 +1332,9 @@ public class SnapshotDiffManager implements AutoCloseable 
{
             return -1L;
           }
 
-          Map.Entry<byte[], SnapshotDiffObject> nextEntry = iterator.next();
+          Map.Entry<byte[], Boolean> nextEntry = iterator.next();
           byte[] id = nextEntry.getKey();
-          SnapshotDiffObject snapshotDiffObject = nextEntry.getValue();
+          boolean isDirectoryObject = nextEntry.getValue();
 
           /*
            * This key can be
@@ -1397,32 +1368,38 @@ public class SnapshotDiffManager implements 
AutoCloseable {
             DiffReportEntry entry =
                 SnapshotDiffReportOzone.getDiffReportEntry(DELETE, key);
             deleteDiffs.add(codecRegistry.asRawData(entry));
-          } else if (Arrays.equals(oldKeyName, newKeyName)) { // Key modified.
+          } else if (isDirectoryObject &&
+              Arrays.equals(oldKeyName, newKeyName)) {
             String key = resolveBucketRelativePath(isFSOBucket,
                 newParentIdPathMap, newKeyName);
             DiffReportEntry entry =
                 SnapshotDiffReportOzone.getDiffReportEntry(MODIFY, key);
             modifyDiffs.add(codecRegistry.asRawData(entry));
-          } else { // Key Renamed.
+          } else {
+            String keyPrefix = getTablePrefix(tablePrefix,
+                (isDirectoryObject ? fsDirTable : fsTable).getName());
             String oldKey = resolveBucketRelativePath(isFSOBucket,
                 oldParentIdPathMap, oldKeyName);
-            String newKey = resolveBucketRelativePath(isFSOBucket,
-                newParentIdPathMap, newKeyName);
-            renameDiffs.add(codecRegistry.asRawData(
-                SnapshotDiffReportOzone.getDiffReportEntry(RENAME, oldKey,
-                    newKey)));
-
             // Check if block location is same or not. If it is not same,
             // key must have been overridden as well.
-            if (isObjectModified(snapshotDiffObject.getOldKeyName(),
-                snapshotDiffObject.getNewKeyName(),
-                snapshotDiffObject.isDirectory() ? fsDirTable : fsTable,
-                snapshotDiffObject.isDirectory() ? tsDirTable : tsTable)) {
+            boolean isObjectModified = isObjectModified(
+                keyPrefix + codecRegistry.asObject(oldKeyName, String.class),
+                keyPrefix + codecRegistry.asObject(newKeyName, String.class),
+                isDirectoryObject ? fsDirTable : fsTable,
+                isDirectoryObject ? tsDirTable : tsTable);
+            if (isObjectModified) {
               // Here, oldKey name is returned as modified. Modified key name 
is
               // based on base snapshot (from snapshot).
-              renameDiffs.add(codecRegistry.asRawData(
+              modifyDiffs.add(codecRegistry.asRawData(
                   SnapshotDiffReportOzone.getDiffReportEntry(MODIFY, oldKey)));
             }
+            if (!isObjectModified || !Arrays.equals(oldKeyName, newKeyName)) {
+              String newKey = resolveBucketRelativePath(isFSOBucket,
+                  newParentIdPathMap, newKeyName);
+              renameDiffs.add(codecRegistry.asRawData(
+                  SnapshotDiffReportOzone.getDiffReportEntry(RENAME, oldKey,
+                      newKey)));
+            }
           }
 
           counter++;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffObject.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffObject.java
deleted file mode 100644
index c99757f364..0000000000
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffObject.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.hadoop.ozone.om.snapshot;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.hadoop.hdds.utils.db.Codec;
-
-import java.io.IOException;
-
-/**
- * SnapshotDiffObject to keep objectId, key's oldName and newName.
- */
-public class SnapshotDiffObject {
-
-  private static final Codec<SnapshotDiffObject> CODEC =
-      new SnapshotDiffObjectCodec();
-
-  public static Codec<SnapshotDiffObject> getCodec() {
-    return CODEC;
-  }
-
-  private long objectId;
-  private String oldKeyName;
-  private String newKeyName;
-
-  private boolean isDirectory;
-
-  // Default constructor for Jackson Serializer.
-  public SnapshotDiffObject() {
-
-  }
-
-  public SnapshotDiffObject(long objectId,
-                            String oldKeyName,
-                            String newKeyName,
-                            boolean isDirectory) {
-    this.objectId = objectId;
-    this.oldKeyName = oldKeyName;
-    this.newKeyName = newKeyName;
-    this.isDirectory = isDirectory;
-  }
-
-  public long getObjectId() {
-    return objectId;
-  }
-
-  public String getOldKeyName() {
-    return oldKeyName;
-  }
-
-  public String getNewKeyName() {
-    return newKeyName;
-  }
-
-  // For Jackson Serializer.
-  public void setObjectId(long objectId) {
-    this.objectId = objectId;
-  }
-
-  // For Jackson Serializer.
-  public void setOldKeyName(String oldKeyName) {
-    this.oldKeyName = oldKeyName;
-  }
-
-  // For Jackson Serializer.
-  public void setNewKeyName(String newKeyName) {
-    this.newKeyName = newKeyName;
-  }
-
-  public void setDirectory(boolean directory) {
-    isDirectory = directory;
-  }
-
-  public boolean isDirectory() {
-    return isDirectory;
-  }
-
-  /**
-   * Builder for SnapshotDiffObject.
-   */
-  public static class SnapshotDiffObjectBuilder {
-    private final long objectId;
-    private String oldKeyName;
-    private String newKeyName;
-
-    private boolean isDirectory;
-
-    public SnapshotDiffObjectBuilder(long objectID) {
-      this.objectId = objectID;
-    }
-
-    public static SnapshotDiffObjectBuilder newBuilder(long objectID) {
-      return new SnapshotDiffObjectBuilder(objectID);
-    }
-
-    public SnapshotDiffObjectBuilder withOldKeyName(String keyName) {
-      this.oldKeyName = keyName;
-      return this;
-    }
-
-    public SnapshotDiffObjectBuilder withNewKeyName(String keyName) {
-      this.newKeyName = keyName;
-      return this;
-    }
-
-    public SnapshotDiffObjectBuilder setIsDirectory(boolean directory) {
-      isDirectory = directory;
-      return this;
-    }
-
-    public SnapshotDiffObject build() {
-      return new SnapshotDiffObject(objectId, oldKeyName, newKeyName,
-          isDirectory);
-    }
-  }
-
-
-  /**
-   * Codec to encode KeyObject as byte array.
-   */
-  private static final class SnapshotDiffObjectCodec
-      implements Codec<SnapshotDiffObject> {
-
-    private static final ObjectMapper MAPPER = new ObjectMapper()
-        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
-        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-
-    @Override
-    public byte[] toPersistedFormat(SnapshotDiffObject object)
-        throws IOException {
-      return MAPPER.writeValueAsBytes(object);
-    }
-
-    @Override
-    public SnapshotDiffObject fromPersistedFormat(byte[] rawData)
-        throws IOException {
-      return MAPPER.readValue(rawData, SnapshotDiffObject.class);
-    }
-
-    @Override
-    public SnapshotDiffObject copyObject(SnapshotDiffObject object) {
-      // Note: Not really a "copy".
-      return object;
-    }
-  }
-}
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotDiffManager.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotDiffManager.java
index 3fa2e9d0a5..d2b9bdffe5 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotDiffManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotDiffManager.java
@@ -54,7 +54,7 @@ import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
 import org.apache.hadoop.ozone.om.helpers.SnapshotDiffJob;
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.helpers.WithParentObjectId;
-import 
org.apache.hadoop.ozone.om.snapshot.SnapshotDiffObject.SnapshotDiffObjectBuilder;
+import org.apache.hadoop.ozone.om.service.SnapshotDeletingService;
 import 
org.apache.hadoop.ozone.om.snapshot.SnapshotTestUtils.StubbedPersistentMap;
 import org.apache.hadoop.ozone.snapshot.CancelSnapshotDiffResponse;
 import 
org.apache.hadoop.ozone.snapshot.CancelSnapshotDiffResponse.CancelMessage;
@@ -690,7 +690,7 @@ public class TestSnapshotDiffManager {
           new StubbedPersistentMap<>();
       PersistentMap<byte[], byte[]> newObjectIdKeyMap =
           new SnapshotTestUtils.StubbedPersistentMap<>();
-      PersistentMap<byte[], SnapshotDiffObject> objectIdsToCheck =
+      PersistentMap<byte[], Boolean> objectIdsToCheck =
           new SnapshotTestUtils.StubbedPersistentMap<>();
 
       Set<Long> oldParentIds = Sets.newHashSet();
@@ -733,11 +733,11 @@ public class TestSnapshotDiffManager {
         assertEquals(12, newObjectIdCnt);
       }
 
-      try (ClosableIterator<Entry<byte[], SnapshotDiffObject>>
+      try (ClosableIterator<Entry<byte[], Boolean>>
                objectIdsToCheckIter = objectIdsToCheck.iterator()) {
         int objectIdCnt = 0;
         while (objectIdsToCheckIter.hasNext()) {
-          Entry<byte[], SnapshotDiffObject> entry = 
objectIdsToCheckIter.next();
+          Entry<byte[], Boolean> entry = objectIdsToCheckIter.next();
           byte[] v = entry.getKey();
           long objectId = codecRegistry.asObject(v, Long.class);
           assertEquals(0, objectId % 2);
@@ -756,40 +756,38 @@ public class TestSnapshotDiffManager {
         new StubbedPersistentMap<>();
     PersistentMap<byte[], byte[]> newObjectIdKeyMap =
         new StubbedPersistentMap<>();
-    PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject =
+    PersistentMap<byte[], Boolean> objectIdToIsDirMap =
         new SnapshotTestUtils.StubbedPersistentMap<>();
     Map<Long, SnapshotDiffReport.DiffType> diffMap = new HashMap<>();
     LongStream.range(0, 100).forEach(objectId -> {
       try {
-        SnapshotDiffObjectBuilder builder =
-            new SnapshotDiffObjectBuilder(objectId);
         String key = "key" + objectId;
         byte[] objectIdVal = codecRegistry.asRawData(objectId);
         byte[] keyBytes = codecRegistry.asRawData(key);
         if (objectId >= 0 && objectId <= 25 ||
             objectId >= 50 && objectId <= 100) {
           oldObjectIdKeyMap.put(objectIdVal, keyBytes);
-          builder.withOldKeyName(key);
         }
-        if (objectId >= 0 && objectId <= 25 && objectId % 4 == 0 ||
+        if (objectId >= 0 && objectId <= 25 &&
+            (objectId % 4 == 0 || objectId % 4 == 2) ||
             objectId > 25 && objectId < 50) {
           newObjectIdKeyMap.put(objectIdVal, keyBytes);
-          builder.withNewKeyName(key);
         }
         if (objectId >= 0 && objectId <= 25 && objectId % 4 == 1) {
           String renamedKey = "renamed-key" + objectId;
           byte[] renamedKeyBytes = codecRegistry.asRawData(renamedKey);
           newObjectIdKeyMap.put(objectIdVal, renamedKeyBytes);
           diffMap.put(objectId, SnapshotDiffReport.DiffType.RENAME);
-          builder.withOldKeyName(key);
-          builder.withNewKeyName(renamedKey);
         }
-        objectIdToDiffObject.put(objectIdVal, builder.build());
+        objectIdToIsDirMap.put(objectIdVal, false);
         if (objectId >= 50 && objectId <= 100 ||
-            objectId >= 0 && objectId <= 25 && objectId % 4 > 1) {
+            objectId >= 0 && objectId <= 25 && objectId % 4 > 2) {
           diffMap.put(objectId, SnapshotDiffReport.DiffType.DELETE);
         }
         if (objectId >= 0 && objectId <= 25 && objectId % 4 == 0) {
+          diffMap.put(objectId, SnapshotDiffReport.DiffType.RENAME);
+        }
+        if (objectId >= 0 && objectId <= 25 && objectId % 4 == 2) {
           diffMap.put(objectId, SnapshotDiffReport.DiffType.MODIFY);
         }
         if (objectId > 25 && objectId < 50) {
@@ -804,55 +802,68 @@ public class TestSnapshotDiffManager {
     String bucketName = "buck";
     String fromSnapName = "fs";
     String toSnapName = "ts";
+    try (MockedStatic<SnapshotDeletingService>
+             mockedSnapshotDeletingService = Mockito.mockStatic(
+                 SnapshotDeletingService.class)) {
+      mockedSnapshotDeletingService.when(() ->
+          SnapshotDeletingService.isBlockLocationInfoSame(any(OmKeyInfo.class),
+              any(OmKeyInfo.class)))
+          .thenAnswer(i -> {
+            int keyVal = Integer.parseInt(((OmKeyInfo)i.getArgument(0))
+                .getKeyName().substring(3));
+            return !(keyVal % 4 == 2 && keyVal >= 0 && keyVal <= 25);
+          });
 
-    OmKeyInfo fromKeyInfo = mock(OmKeyInfo.class);
-    OmKeyInfo toKeyInfo = mock(OmKeyInfo.class);
-    // This is temporary to make sure that
-    // SnapshotDeletingService#isBlockLocationInfoSame always return true.
-    when(toKeyInfo.isHsync()).thenReturn(true);
-    when(fromKeyInfo.isHsync()).thenReturn(true);
-
-    Table<String, OmKeyInfo> fromSnapTable = mock(Table.class);
-    Table<String, OmKeyInfo> toSnapTable = mock(Table.class);
-    when(fromSnapTable.get(anyString())).thenReturn(fromKeyInfo);
-    when(toSnapTable.get(anyString())).thenReturn(toKeyInfo);
-
-
-    SnapshotDiffManager spy = spy(snapshotDiffManager);
-    doReturn(true).when(spy)
-        .areDiffJobAndSnapshotsActive(volumeName, bucketName, fromSnapName,
-            toSnapName);
-
-    long totalDiffEntries = spy.generateDiffReport("jobId",
-        fromSnapTable, toSnapTable, null, null,
-        objectIdToDiffObject, oldObjectIdKeyMap, newObjectIdKeyMap, volumeName,
-        bucketName, fromSnapName, toSnapName, false, Optional.empty(),
-        Optional.empty());
-
-    assertEquals(100, totalDiffEntries);
-    SnapshotDiffJob snapshotDiffJob = new SnapshotDiffJob(0, "jobId",
-        JobStatus.DONE, "vol", "buck", "fs", "ts", false,
-        true, diffMap.size());
-    SnapshotDiffReportOzone snapshotDiffReportOzone =
-        snapshotDiffManager.createPageResponse(snapshotDiffJob, "vol",
-            "buck", "fs", "ts",
-            0, Integer.MAX_VALUE);
-    Set<SnapshotDiffReport.DiffType> expectedOrder = new LinkedHashSet<>();
-    expectedOrder.add(SnapshotDiffReport.DiffType.DELETE);
-    expectedOrder.add(SnapshotDiffReport.DiffType.RENAME);
-    expectedOrder.add(SnapshotDiffReport.DiffType.CREATE);
-    expectedOrder.add(SnapshotDiffReport.DiffType.MODIFY);
-
-    Set<SnapshotDiffReport.DiffType> actualOrder = new LinkedHashSet<>();
-    for (DiffReportEntry entry :
-        snapshotDiffReportOzone.getDiffList()) {
-      actualOrder.add(entry.getType());
-
-      long objectId = Long.parseLong(
-          DFSUtilClient.bytes2String(entry.getSourcePath()).substring(3));
-      assertEquals(diffMap.get(objectId), entry.getType());
+      Table<String, OmKeyInfo> fromSnapTable = mock(Table.class);
+      Table<String, OmKeyInfo> toSnapTable = mock(Table.class);
+      when(fromSnapTable.get(anyString())).thenAnswer(i -> {
+        OmKeyInfo keyInfo = mock(OmKeyInfo.class);
+        Mockito.when(keyInfo.getKeyName()).thenReturn(i.getArgument(0));
+        return keyInfo;
+      });
+      when(toSnapTable.get(anyString())).thenAnswer(i -> {
+        OmKeyInfo keyInfo = mock(OmKeyInfo.class);
+        Mockito.when(keyInfo.getKeyName()).thenReturn(i.getArgument(0));
+        return keyInfo;
+      });
+      when(fromSnapTable.getName()).thenReturn("table");
+      Map<String, String> tablePrefixes = Mockito.mock(Map.class);
+      Mockito.when(tablePrefixes.get(anyString())).thenReturn("");
+      SnapshotDiffManager spy = spy(snapshotDiffManager);
+      doReturn(true).when(spy)
+          .areDiffJobAndSnapshotsActive(volumeName, bucketName, fromSnapName,
+              toSnapName);
+
+      long totalDiffEntries = spy.generateDiffReport("jobId",
+          fromSnapTable, toSnapTable, null, null,
+          objectIdToIsDirMap, oldObjectIdKeyMap, newObjectIdKeyMap,
+          volumeName, bucketName, fromSnapName, toSnapName, false,
+          Optional.empty(), Optional.empty(), tablePrefixes);
+
+      assertEquals(100, totalDiffEntries);
+      SnapshotDiffJob snapshotDiffJob = new SnapshotDiffJob(0, "jobId",
+          JobStatus.DONE, "vol", "buck", "fs", "ts", false,
+          true, diffMap.size());
+      SnapshotDiffReportOzone snapshotDiffReportOzone =
+          snapshotDiffManager.createPageResponse(snapshotDiffJob, "vol",
+              "buck", "fs", "ts",
+              0, Integer.MAX_VALUE);
+      Set<SnapshotDiffReport.DiffType> expectedOrder = new LinkedHashSet<>();
+      expectedOrder.add(SnapshotDiffReport.DiffType.DELETE);
+      expectedOrder.add(SnapshotDiffReport.DiffType.RENAME);
+      expectedOrder.add(SnapshotDiffReport.DiffType.CREATE);
+      expectedOrder.add(SnapshotDiffReport.DiffType.MODIFY);
+
+      Set<SnapshotDiffReport.DiffType> actualOrder = new LinkedHashSet<>();
+      for (DiffReportEntry entry :
+          snapshotDiffReportOzone.getDiffList()) {
+        actualOrder.add(entry.getType());
+        long objectId = Long.parseLong(
+            DFSUtilClient.bytes2String(entry.getSourcePath()).substring(3));
+        assertEquals(diffMap.get(objectId), entry.getType());
+      }
+      assertEquals(expectedOrder, actualOrder);
     }
-    assertEquals(expectedOrder, actualOrder);
   }
 
   private DiffReportEntry getTestDiffEntry(String jobId,
@@ -1185,19 +1196,18 @@ public class TestSnapshotDiffManager {
 
   @Test
   public void testGenerateDiffReportWhenThereInEntry() {
-    PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject =
+    PersistentMap<byte[], Boolean> objectIdToIsDirectoryMap =
         new StubbedPersistentMap<>();
     PersistentMap<byte[], byte[]> oldObjIdToKeyMap =
         new StubbedPersistentMap<>();
     PersistentMap<byte[], byte[]> newObjIdToKeyMap =
         new StubbedPersistentMap<>();
-
     long totalDiffEntries = snapshotDiffManager.generateDiffReport("jobId",
         keyInfoTable,
         keyInfoTable,
         null,
         null,
-        objectIdToDiffObject,
+        objectIdToIsDirectoryMap,
         oldObjIdToKeyMap,
         newObjIdToKeyMap,
         "volume",
@@ -1206,7 +1216,8 @@ public class TestSnapshotDiffManager {
         "toSnapshot",
         false,
         Optional.empty(),
-        Optional.empty());
+        Optional.empty(),
+        Collections.emptyMap());
 
     assertEquals(0, totalDiffEntries);
   }
@@ -1218,14 +1229,14 @@ public class TestSnapshotDiffManager {
     String fromSnapshotName = "snap-" + RandomStringUtils.randomNumeric(5);
     String toSnapshotName = "snap-" + RandomStringUtils.randomNumeric(5);
 
-    PersistentMap<byte[], SnapshotDiffObject> objectIdToDiffObject =
+    PersistentMap<byte[], Boolean> objectIdToIsDirectoryMap =
         new SnapshotTestUtils.StubbedPersistentMap<>();
     PersistentMap<byte[], byte[]> oldObjIdToKeyMap =
         new StubbedPersistentMap<>();
     PersistentMap<byte[], byte[]> newObjIdToKeyMap =
         new StubbedPersistentMap<>();
-    objectIdToDiffObject.put(codecRegistry.asRawData("randomKey"),
-        new SnapshotDiffObjectBuilder(1L).build());
+    objectIdToIsDirectoryMap.put(codecRegistry.asRawData("randomKey"),
+        false);
 
     SnapshotDiffManager spy = spy(snapshotDiffManager);
     doReturn(true).when(spy)
@@ -1238,7 +1249,7 @@ public class TestSnapshotDiffManager {
             keyInfoTable,
             null,
             null,
-            objectIdToDiffObject,
+            objectIdToIsDirectoryMap,
             oldObjIdToKeyMap,
             newObjIdToKeyMap,
             volumeName,
@@ -1247,7 +1258,8 @@ public class TestSnapshotDiffManager {
             toSnapshotName,
             false,
             Optional.empty(),
-            Optional.empty())
+            Optional.empty(),
+            Collections.emptyMap())
     );
     assertEquals("Old and new key name both are null",
         exception.getMessage());
@@ -1511,7 +1523,7 @@ public class TestSnapshotDiffManager {
     doReturn(10L).when(spy).generateDiffReport(anyString(),
         any(), any(), any(), any(), any(), any(), any(),
         anyString(), anyString(), anyString(), anyString(), anyBoolean(),
-        any(), any());
+        any(), any(), anyMap());
     doReturn(LEGACY).when(spy).getBucketLayout(VOLUME_NAME, BUCKET_NAME,
         omMetadataManager);
 


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


Reply via email to