/**
  * 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);
     }
   }
 }
예제 #2
0
 /**
  * Find the latest snapshot that 1) covers the given inode (which means the snapshot was either
  * taken on the inode or taken on an ancestor of the inode), and 2) was taken before the given
  * snapshot (if the given snapshot is not null).
  *
  * @param inode the given inode that the returned snapshot needs to cover
  * @param anchor the returned snapshot should be taken before this given id.
  * @return id of the latest snapshot that covers the given inode and was taken before the the
  *     given snapshot (if it is not null).
  */
 public static int findLatestSnapshot(INode inode, final int anchor) {
   int latest = NO_SNAPSHOT_ID;
   for (; inode != null; inode = inode.getParent()) {
     if (inode.isDirectory()) {
       final INodeDirectory dir = inode.asDirectory();
       if (dir.isWithSnapshot()) {
         latest = dir.getDiffs().updatePrior(anchor, latest);
       }
     }
   }
   return latest;
 }
 /** Load the snapshot diff section from fsimage. */
 public void loadSnapshotDiffSection(InputStream in) throws IOException {
   final List<INodeReference> refList = parent.getLoaderContext().getRefList();
   while (true) {
     SnapshotDiffSection.DiffEntry entry = SnapshotDiffSection.DiffEntry.parseDelimitedFrom(in);
     if (entry == null) {
       break;
     }
     long inodeId = entry.getInodeId();
     INode inode = fsDir.getInode(inodeId);
     SnapshotDiffSection.DiffEntry.Type type = entry.getType();
     switch (type) {
       case FILEDIFF:
         loadFileDiffList(in, inode.asFile(), entry.getNumOfDiff());
         break;
       case DIRECTORYDIFF:
         loadDirectoryDiffList(in, inode.asDirectory(), entry.getNumOfDiff(), refList);
         break;
     }
   }
 }
예제 #4
0
 static Snapshot read(DataInput in, FSImageFormat.Loader loader) throws IOException {
   final int snapshotId = in.readInt();
   final INode root = loader.loadINodeWithLocalName(false, in, false);
   return new Snapshot(snapshotId, root.asDirectory(), null);
 }