/// <summary> /// Compute the difference between two snapshots (or a snapshot and the current /// directory) of the directory. /// </summary> /// <param name="from"> /// The name of the start point of the comparison. Null indicating /// the current tree. /// </param> /// <param name="to">The name of the end point. Null indicating the current tree.</param> /// <returns>The difference between the start/end points.</returns> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotException"> /// If there is no snapshot matching the starting /// point, or if endSnapshotName is not null but cannot be identified /// as a previous snapshot. /// </exception> internal virtual SnapshotDiffInfo ComputeDiff(INodeDirectory snapshotRoot, string from, string to) { Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot fromSnapshot = GetSnapshotByName (snapshotRoot, from); Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot toSnapshot = GetSnapshotByName (snapshotRoot, to); // if the start point is equal to the end point, return null if (from.Equals(to)) { return(null); } SnapshotDiffInfo diffs = new SnapshotDiffInfo(snapshotRoot, fromSnapshot, toSnapshot ); ComputeDiffRecursively(snapshotRoot, snapshotRoot, new AList <byte[]>(), diffs); return(diffs); }
/// <summary> /// Compute the difference between two snapshots of a directory, or between a /// snapshot of the directory and its current tree. /// </summary> /// <exception cref="System.IO.IOException"/> public virtual SnapshotDiffReport Diff(INodesInPath iip, string snapshotRootPath, string from, string to) { // Find the source root directory path where the snapshots were taken. // All the check for path has been included in the valueOf method. INodeDirectory snapshotRoot = GetSnapshottableRoot(iip); if ((from == null || from.IsEmpty()) && (to == null || to.IsEmpty())) { // both fromSnapshot and toSnapshot indicate the current tree return(new SnapshotDiffReport(snapshotRootPath, from, to, Sharpen.Collections.EmptyList <SnapshotDiffReport.DiffReportEntry>())); } SnapshotDiffInfo diffs = snapshotRoot.GetDirectorySnapshottableFeature().ComputeDiff (snapshotRoot, from, to); return(diffs != null?diffs.GenerateReport() : new SnapshotDiffReport(snapshotRootPath , from, to, Sharpen.Collections.EmptyList <SnapshotDiffReport.DiffReportEntry>())); }
/// <summary> /// Recursively compute the difference between snapshots under a given /// directory/file. /// </summary> /// <param name="snapshotRoot">The directory where snapshots were taken.</param> /// <param name="node">The directory/file under which the diff is computed.</param> /// <param name="parentPath"> /// Relative path (corresponding to the snapshot root) of /// the node's parent. /// </param> /// <param name="diffReport">data structure used to store the diff.</param> private void ComputeDiffRecursively(INodeDirectory snapshotRoot, INode node, IList <byte[]> parentPath, SnapshotDiffInfo diffReport) { Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot earlierSnapshot = diffReport .IsFromEarlier() ? diffReport.GetFrom() : diffReport.GetTo(); Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot laterSnapshot = diffReport .IsFromEarlier() ? diffReport.GetTo() : diffReport.GetFrom(); byte[][] relativePath = Sharpen.Collections.ToArray(parentPath, new byte[parentPath .Count][]); if (node.IsDirectory()) { DirectoryWithSnapshotFeature.ChildrenDiff diff = new DirectoryWithSnapshotFeature.ChildrenDiff (); INodeDirectory dir = node.AsDirectory(); DirectoryWithSnapshotFeature sf = dir.GetDirectoryWithSnapshotFeature(); if (sf != null) { bool change = sf.ComputeDiffBetweenSnapshots(earlierSnapshot, laterSnapshot, diff , dir); if (change) { diffReport.AddDirDiff(dir, relativePath, diff); } } ReadOnlyList <INode> children = dir.GetChildrenList(earlierSnapshot.GetId()); foreach (INode child in children) { byte[] name = child.GetLocalNameBytes(); bool toProcess = diff.SearchIndex(Diff.ListType.Deleted, name) < 0; if (!toProcess && child is INodeReference.WithName) { byte[][] renameTargetPath = FindRenameTargetPath(snapshotRoot, (INodeReference.WithName )child, laterSnapshot == null ? Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId : laterSnapshot.GetId()); if (renameTargetPath != null) { toProcess = true; diffReport.SetRenameTarget(child.GetId(), renameTargetPath); } } if (toProcess) { parentPath.AddItem(name); ComputeDiffRecursively(snapshotRoot, child, parentPath, diffReport); parentPath.Remove(parentPath.Count - 1); } } } else { if (node.IsFile() && node.AsFile().IsWithSnapshot()) { INodeFile file = node.AsFile(); bool change = file.GetFileWithSnapshotFeature().ChangedBetweenSnapshots(file, earlierSnapshot , laterSnapshot); if (change) { diffReport.AddFileDiff(file, relativePath); } } } }