diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/AbstractINodeDiffList.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/AbstractINodeDiffList.java index 5163e5ece5..d1156564c2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/AbstractINodeDiffList.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/AbstractINodeDiffList.java @@ -235,6 +235,12 @@ abstract class AbstractINodeDiffList iterator() { return diffs != null ? diffs.iterator() : Collections.emptyIterator(); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DirectoryWithSnapshotFeature.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DirectoryWithSnapshotFeature.java index b3ce602463..19be8f8958 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DirectoryWithSnapshotFeature.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DirectoryWithSnapshotFeature.java @@ -228,12 +228,18 @@ public class DirectoryWithSnapshotFeature implements INode.Feature { private List initChildren() { if (children == null) { final ChildrenDiff combined = new ChildrenDiff(); - for (DirectoryDiff d = DirectoryDiff.this; d != null; - d = d.getPosterior()) { + DirectoryDiffList directoryDiffList = + currentDir.getDirectoryWithSnapshotFeature().diffs; + final int diffIndex = + directoryDiffList.getDiffIndexById(getSnapshotId()); + List diffList = directoryDiffList + .getDiffListBetweenSnapshots(diffIndex, + directoryDiffList.asList().size(), currentDir); + for (DirectoryDiff d : diffList) { combined.combinePosterior(d.diff, null); } - children = combined.apply2Current(ReadOnlyList.Util.asList( - currentDir.getChildrenList(Snapshot.CURRENT_STATE_ID))); + children = combined.apply2Current(ReadOnlyList.Util + .asList(currentDir.getChildrenList(Snapshot.CURRENT_STATE_ID))); } return children; } @@ -383,6 +389,19 @@ public class DirectoryWithSnapshotFeature implements INode.Feature { } return NO_SNAPSHOT_ID; } + + /** + * Returns the list of diffs between two indexes corresponding to two + * snapshots. + * @param fromIndex Index of the diff corresponding to the earlier snapshot + * @param toIndex Index of the diff corresponding to the later snapshot + * @param dir The Directory to which the diffList belongs + * @return list of directory diffs + */ + List getDiffListBetweenSnapshots(int fromIndex, int toIndex, + INodeDirectory dir) { + return asList().getMinListForRange(fromIndex, toIndex, dir); + } } private static Map cloneDiffList(List diffList) { @@ -597,7 +616,7 @@ public class DirectoryWithSnapshotFeature implements INode.Feature { return diff != null ? diff.getChild(name, true, currentINode) : currentINode.getChild(name, Snapshot.CURRENT_STATE_ID); } - + /** Used to record the modification of a symlink node */ public INode saveChild2Snapshot(INodeDirectory currentINode, final INode child, final int latestSnapshotId, final INode snapshotCopy) { @@ -678,9 +697,10 @@ public class DirectoryWithSnapshotFeature implements INode.Feature { boolean dirMetadataChanged = false; INodeDirectoryAttributes dirCopy = null; - DiffList difflist = diffs.asList(); - for (int i = earlierDiffIndex; i < laterDiffIndex; i++) { - DirectoryDiff sdiff = difflist.get(i); + List difflist = diffs + .getDiffListBetweenSnapshots(earlierDiffIndex, laterDiffIndex, + currentINode); + for (DirectoryDiff sdiff : difflist) { diff.combinePosterior(sdiff.diff, null); if (!dirMetadataChanged && sdiff.snapshotINode != null) { if (dirCopy == null) {