@Override public int size() { return diffs.size(); }
/** @return the last diff. */ public final D getLast() { if (diffs == null) { return null; } int n = diffs.size(); return n == 0 ? null : diffs.get(n - 1); }
/** Replace the given child in the created/deleted list, if there is any. */ public boolean replaceCreatedChild(final INode oldChild, final INode newChild) { final DiffList<DirectoryDiff> diffList = asList(); for(int i = diffList.size() - 1; i >= 0; i--) { final ChildrenDiff diff = diffList.get(i).diff; if (diff.replaceCreated(oldChild, newChild)) { return true; } } return false; }
/** * Save SnapshotDiff list for an INodeDirectoryWithSnapshot. * @param sNode The directory that the SnapshotDiff list belongs to. * @param out The {@link DataOutput} to write. */ private static <N extends INode, A extends INodeAttributes, D extends AbstractINodeDiff<N, A, D>> void saveINodeDiffs(final AbstractINodeDiffList<N, A, D> diffs, final DataOutput out, ReferenceMap referenceMap) throws IOException { // Record the diffs in reversed order, so that we can find the correct // reference for INodes in the created list when loading the FSImage if (diffs == null) { out.writeInt(-1); // no diffs } else { final DiffList<D> list = diffs.asList(); final int size = list.size(); out.writeInt(size); for (int i = size - 1; i >= 0; i--) { list.get(i).write(out, referenceMap); } } }
/** Remove the given child from the deleted list, if there is any. */ public boolean removeDeletedChild(final INode child) { final DiffList<DirectoryDiff> diffList = asList(); for(int i = diffList.size() - 1; i >= 0; i--) { final ChildrenDiff diff = diffList.get(i).diff; if (diff.removeDeleted(child)) { return true; } } return false; }
public final D getDiffById(final int snapshotId) { if (snapshotId == Snapshot.CURRENT_STATE_ID || diffs == null) { return null; } final int i = diffs.binarySearch(snapshotId); if (i >= 0) { // exact match return diffs.get(i); } else { // Exact match not found means that there were no changes between // given snapshot and the next state so that the diff for the given // snapshot was not recorded. Thus, return the next state. final int j = -i - 1; return j < diffs.size() ? diffs.get(j) : null; } }
final int[] changedBetweenSnapshots(Snapshot from, Snapshot to) { if (diffs == null) { return null; } Snapshot earlier = from; Snapshot later = to; if (Snapshot.ID_COMPARATOR.compare(from, to) > 0) { earlier = to; later = from; } final int size = diffs.size(); int earlierDiffIndex = getDiffIndexById(earlier.getId()); int laterDiffIndex = later == null ? size : getDiffIndexById(later.getId()); if (earlierDiffIndex == size) { // if the earlierSnapshot is after the latest SnapshotDiff stored in // diffs, no modification happened after the earlierSnapshot return null; } if (laterDiffIndex == -1 || laterDiffIndex == 0) { // if the laterSnapshot is the earliest SnapshotDiff stored in diffs, or // before it, no modification happened before the laterSnapshot return null; } return new int[]{earlierDiffIndex, laterDiffIndex}; }
public BlockInfo[] findLaterSnapshotBlocks(int snapshotId) { assert snapshotId != Snapshot.NO_SNAPSHOT_ID : "Wrong snapshot id"; if (snapshotId == Snapshot.CURRENT_STATE_ID) { return null; } DiffList<FileDiff> diffs = this.asList(); int i = diffs.binarySearch(snapshotId); BlockInfo[] blocks = null; for (i = i >= 0 ? i+1 : -i-1; i < diffs.size(); i++) { blocks = diffs.get(i).getBlocks(); if (blocks != null) { break; } } return blocks; }
/** remove DirectorySnapshottableFeature */ public void removeSnapshottableFeature() { DirectorySnapshottableFeature s = getDirectorySnapshottableFeature(); Preconditions.checkState(s != null, "The dir does not have snapshottable feature: this=%s", this); this.removeFeature(s); if (s.getDiffs().asList().size() > 0) { // add a DirectoryWithSnapshotFeature back DirectoryWithSnapshotFeature sf = new DirectoryWithSnapshotFeature( s.getDiffs()); addFeature(sf); } }
/** * Find the corresponding snapshot whose deleted list contains the given * inode. * @return the id of the snapshot. {@link Snapshot#NO_SNAPSHOT_ID} if the * given inode is not in any of the snapshot. */ public int findSnapshotDeleted(final INode child) { final DiffList<DirectoryDiff> diffList = asList(); for(int i = diffList.size() - 1; i >= 0; i--) { final DirectoryDiff diff = diffList.get(i); if (diff.getChildrenDiff().containsDeleted(child)) { return diff.getSnapshotId(); } } return NO_SNAPSHOT_ID; }
final long laterLength = laterDiffIndex == diffList.size() ? file .computeFileSize(true, false) : diffList.get(laterDiffIndex) .getFileSize();
SnapshotDiffSection.DiffEntry entry = SnapshotDiffSection.DiffEntry .newBuilder().setInodeId(dir.getId()).setType(Type.DIRECTORYDIFF) .setNumOfDiff(diffList.size()).build(); entry.writeDelimitedTo(out); for (int i = diffList.size() - 1; i >= 0; i--) { // reverse order! DirectoryDiff diff = diffList.get(i); SnapshotDiffSection.DirectoryDiff.Builder db = SnapshotDiffSection.
private void serializeFileDiffList(INodeFile file, OutputStream out) throws IOException { FileWithSnapshotFeature sf = file.getFileWithSnapshotFeature(); if (sf != null) { DiffList<FileDiff> diffList = sf.getDiffs().asList(); SnapshotDiffSection.DiffEntry entry = SnapshotDiffSection.DiffEntry .newBuilder().setInodeId(file.getId()).setType(Type.FILEDIFF) .setNumOfDiff(diffList.size()).build(); entry.writeDelimitedTo(out); for (int i = diffList.size() - 1; i >= 0; i--) { FileDiff diff = diffList.get(i); SnapshotDiffSection.FileDiff.Builder fb = SnapshotDiffSection.FileDiff .newBuilder().setSnapshotId(diff.getSnapshotId()) .setFileSize(diff.getFileSize()); if(diff.getBlocks() != null) { for(Block block : diff.getBlocks()) { fb.addBlocks(PBHelperClient.convert(block)); } } INodeFileAttributes copy = diff.snapshotINode; if (copy != null) { fb.setName(ByteString.copyFrom(copy.getLocalNameBytes())) .setSnapshotCopy(buildINodeFile(copy, parent.getSaverContext())); } fb.build().writeDelimitedTo(out); } } }