/** * Recursively compute the difference between snapshots under a given directory/file. * * @param node The directory/file under which the diff is computed. * @param parentPath Relative path (corresponding to the snapshot root) of the node's parent. * @param diffReport data structure used to store the diff. */ private void computeDiffRecursively( INode node, List<byte[]> parentPath, SnapshotDiffInfo diffReport) { ChildrenDiff diff = new ChildrenDiff(); byte[][] relativePath = parentPath.toArray(new byte[parentPath.size()][]); if (node.isDirectory()) { INodeDirectory dir = node.asDirectory(); if (dir instanceof INodeDirectoryWithSnapshot) { INodeDirectoryWithSnapshot sdir = (INodeDirectoryWithSnapshot) dir; boolean change = sdir.computeDiffBetweenSnapshots(diffReport.from, diffReport.to, diff); if (change) { diffReport.addDirDiff(sdir, relativePath, diff); } } ReadOnlyList<INode> children = dir.getChildrenList(diffReport.isFromEarlier() ? diffReport.to : diffReport.from); for (INode child : children) { final byte[] name = child.getLocalNameBytes(); if (diff.searchIndex(ListType.CREATED, name) < 0 && diff.searchIndex(ListType.DELETED, name) < 0) { parentPath.add(name); computeDiffRecursively(child, parentPath, diffReport); parentPath.remove(parentPath.size() - 1); } } } else if (node.isFile() && node.asFile() instanceof FileWithSnapshot) { FileWithSnapshot file = (FileWithSnapshot) node.asFile(); Snapshot earlierSnapshot = diffReport.isFromEarlier() ? diffReport.from : diffReport.to; Snapshot laterSnapshot = diffReport.isFromEarlier() ? diffReport.to : diffReport.from; boolean change = file.getDiffs().changedBetweenSnapshots(earlierSnapshot, laterSnapshot); if (change) { diffReport.addFileDiff(file.asINodeFile(), relativePath); } } }
/** * Compute the difference between two snapshots (or a snapshot and the current directory) of the * directory. * * @param from The name of the start point of the comparison. Null indicating the current tree. * @param to The name of the end point. Null indicating the current tree. * @return The difference between the start/end points. * @throws SnapshotException If there is no snapshot matching the starting point, or if * endSnapshotName is not null but cannot be identified as a previous snapshot. */ SnapshotDiffInfo computeDiff(final String from, final String to) throws SnapshotException { Snapshot fromSnapshot = getSnapshotByName(from); Snapshot toSnapshot = getSnapshotByName(to); // if the start point is equal to the end point, return null if (from.equals(to)) { return null; } SnapshotDiffInfo diffs = new SnapshotDiffInfo(this, fromSnapshot, toSnapshot); computeDiffRecursively(this, new ArrayList<byte[]>(), diffs); return diffs; }