/// <summary> /// If some blocks at the end of the block list no longer belongs to /// any inode, collect them and update the block list. /// </summary> public virtual void CollectBlocksAndClear(BlockStoragePolicySuite bsps, INodeFile file, INode.BlocksMapUpdateInfo info, IList <INode> removedINodes) { // check if everything is deleted. if (IsCurrentFileDeleted() && GetDiffs().AsList().IsEmpty()) { file.DestroyAndCollectBlocks(bsps, info, removedINodes); return; } // find max file size. long max; FileDiff diff = GetDiffs().GetLast(); if (IsCurrentFileDeleted()) { max = diff == null ? 0 : diff.GetFileSize(); } else { max = file.ComputeFileSize(); } // Collect blocks that should be deleted FileDiff last = diffs.GetLast(); BlockInfoContiguous[] snapshotBlocks = last == null ? null : last.GetBlocks(); if (snapshotBlocks == null) { file.CollectBlocksBeyondMax(max, info); } else { file.CollectBlocksBeyondSnapshot(snapshotBlocks, info); } }
public virtual void DestroyAndCollectSnapshotBlocks(INode.BlocksMapUpdateInfo collectedBlocks ) { foreach (FileDiff d in AsList()) { d.DestroyAndCollectSnapshotBlocks(collectedBlocks); } }
/// <summary>Delete a snapshot for a snapshottable directory</summary> /// <param name="snapshotName">Name of the snapshot to be deleted</param> /// <param name="collectedBlocks">Used to collect information to update blocksMap</param> /// <exception cref="System.IO.IOException"/> public virtual void DeleteSnapshot(INodesInPath iip, string snapshotName, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { INodeDirectory srcRoot = GetSnapshottableRoot(iip); srcRoot.RemoveSnapshot(fsdir.GetBlockStoragePolicySuite(), snapshotName, collectedBlocks , removedINodes); numSnapshots.GetAndDecrement(); }
internal override QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite bsps, INodeDirectory currentDir, DirectoryWithSnapshotFeature.DirectoryDiff posterior , INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { QuotaCounts counts = new QuotaCounts.Builder().Build(); diff.CombinePosterior(posterior.diff, new _Processor_218(bsps, counts, collectedBlocks , removedINodes)); return(counts); }
internal override QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite bsps, INodeFile currentINode, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.FileDiff posterior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes ) { FileWithSnapshotFeature sf = currentINode.GetFileWithSnapshotFeature(); System.Diagnostics.Debug.Assert(sf != null, "FileWithSnapshotFeature is null"); return(sf.UpdateQuotaAndCollectBlocks(bsps, currentINode, posterior, collectedBlocks , removedINodes)); }
public virtual void Clear(BlockStoragePolicySuite bsps, INodeDirectory currentINode , INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { // destroy its diff list foreach (DirectoryWithSnapshotFeature.DirectoryDiff diff in diffs) { diff.DestroyDiffAndCollectBlocks(bsps, currentINode, collectedBlocks, removedINodes ); } diffs.Clear(); }
public virtual void DestroyAndCollectSnapshotBlocks(INode.BlocksMapUpdateInfo collectedBlocks ) { if (blocks == null || collectedBlocks == null) { return; } foreach (BlockInfoContiguous blk in blocks) { collectedBlocks.AddDeleteBlock(blk); } blocks = null; }
/// <summary>Delete a snapshot.</summary> /// <remarks> /// Delete a snapshot. The synchronization of the diff list will be done /// outside. If the diff to remove is not the first one in the diff list, we /// need to combine the diff with its previous one. /// </remarks> /// <param name="snapshot">The id of the snapshot to be deleted</param> /// <param name="prior">The id of the snapshot taken before the to-be-deleted snapshot /// </param> /// <param name="collectedBlocks">Used to collect information for blocksMap update</param> /// <returns>delta in namespace.</returns> public QuotaCounts DeleteSnapshotDiff(BlockStoragePolicySuite bsps, int snapshot, int prior, N currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode > removedINodes) { int snapshotIndex = Sharpen.Collections.BinarySearch(diffs, snapshot); QuotaCounts counts = new QuotaCounts.Builder().Build(); D removed = null; if (snapshotIndex == 0) { if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId) { // there is still snapshot before // set the snapshot to latestBefore diffs[snapshotIndex].SetSnapshotId(prior); } else { // there is no snapshot before removed = diffs.Remove(0); counts.Add(removed.DestroyDiffAndCollectBlocks(bsps, currentINode, collectedBlocks , removedINodes)); } } else { if (snapshotIndex > 0) { AbstractINodeDiff <N, A, D> previous = diffs[snapshotIndex - 1]; if (previous.GetSnapshotId() != prior) { diffs[snapshotIndex].SetSnapshotId(prior); } else { // combine the to-be-removed diff with its previous diff removed = diffs.Remove(snapshotIndex); if (previous.snapshotINode == null) { previous.snapshotINode = removed.snapshotINode; } counts.Add(previous.CombinePosteriorAndCollectBlocks(bsps, currentINode, removed, collectedBlocks, removedINodes)); previous.SetPosterior(removed.GetPosterior()); removed.SetPosterior(null); } } } return(counts); }
/// <summary>clear the deleted list</summary> private QuotaCounts DestroyDeletedList(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { QuotaCounts counts = new QuotaCounts.Builder().Build(); IList <INode> deletedList = GetList(Diff.ListType.Deleted); foreach (INode d in deletedList) { d.ComputeQuotaUsage(bsps, counts, false); d.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes); } deletedList.Clear(); return(counts); }
/// <summary>clear the created list</summary> private QuotaCounts DestroyCreatedList(BlockStoragePolicySuite bsps, INodeDirectory currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes ) { QuotaCounts counts = new QuotaCounts.Builder().Build(); IList <INode> createdList = GetList(Diff.ListType.Created); foreach (INode c in createdList) { c.ComputeQuotaUsage(bsps, counts, true); c.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes); // c should be contained in the children list, remove it currentINode.RemoveChild(c); } createdList.Clear(); return(counts); }
/// <summary> /// Remove the snapshot with the given name from /// <see cref="snapshotsByNames"/> /// , /// and delete all the corresponding DirectoryDiff. /// </summary> /// <param name="snapshotRoot">The directory where we take snapshots</param> /// <param name="snapshotName">The name of the snapshot to be removed</param> /// <param name="collectedBlocks">Used to collect information to update blocksMap</param> /// <returns> /// The removed snapshot. Null if no snapshot with the given name /// exists. /// </returns> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotException"/> public virtual Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot RemoveSnapshot (BlockStoragePolicySuite bsps, INodeDirectory snapshotRoot, string snapshotName, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { int i = SearchSnapshot(DFSUtil.String2Bytes(snapshotName)); if (i < 0) { throw new SnapshotException("Cannot delete snapshot " + snapshotName + " from path " + snapshotRoot.GetFullPathName() + ": the snapshot does not exist."); } else { Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot snapshot = snapshotsByNames [i]; int prior = Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.FindLatestSnapshot (snapshotRoot, snapshot.GetId()); try { QuotaCounts counts = snapshotRoot.CleanSubtree(bsps, snapshot.GetId(), prior, collectedBlocks , removedINodes); INodeDirectory parent = snapshotRoot.GetParent(); if (parent != null) { // there will not be any WithName node corresponding to the deleted // snapshot, thus only update the quota usage in the current tree parent.AddSpaceConsumed(counts.Negation(), true); } } catch (QuotaExceededException e) { INode.Log.Error("BUG: removeSnapshot increases namespace usage.", e); } // remove from snapshotsByNames after successfully cleaning the subtree snapshotsByNames.Remove(i); return(snapshot); } }
public virtual QuotaCounts CleanFile(BlockStoragePolicySuite bsps, INodeFile file , int snapshotId, int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks , IList <INode> removedINodes) { if (snapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId) { // delete the current file while the file has snapshot feature if (!IsCurrentFileDeleted()) { file.RecordModification(priorSnapshotId); DeleteCurrentFile(); } CollectBlocksAndClear(bsps, file, collectedBlocks, removedINodes); return(new QuotaCounts.Builder().Build()); } else { // delete the snapshot priorSnapshotId = GetDiffs().UpdatePrior(snapshotId, priorSnapshotId); return(diffs.DeleteSnapshotDiff(bsps, snapshotId, priorSnapshotId, file, collectedBlocks , removedINodes)); } }
internal override QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite bsps, INodeFile currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList < INode> removedINodes) { return(currentINode.GetFileWithSnapshotFeature().UpdateQuotaAndCollectBlocks(bsps , currentINode, this, collectedBlocks, removedINodes)); }
/// <summary> /// Copy blocks from the removed snapshot into the previous snapshot /// up to the file length of the latter. /// </summary> /// <remarks> /// Copy blocks from the removed snapshot into the previous snapshot /// up to the file length of the latter. /// Collect unused blocks of the removed snapshot. /// </remarks> internal virtual void CombineAndCollectSnapshotBlocks(BlockStoragePolicySuite bsps , INodeFile file, FileDiff removed, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { BlockInfoContiguous[] removedBlocks = removed.GetBlocks(); if (removedBlocks == null) { FileWithSnapshotFeature sf = file.GetFileWithSnapshotFeature(); System.Diagnostics.Debug.Assert(sf != null, "FileWithSnapshotFeature is null"); if (sf.IsCurrentFileDeleted()) { sf.CollectBlocksAndClear(bsps, file, collectedBlocks, removedINodes); } return; } int p = GetPrior(removed.GetSnapshotId(), true); FileDiff earlierDiff = p == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .NoSnapshotId ? null : GetDiffById(p); // Copy blocks to the previous snapshot if not set already if (earlierDiff != null) { earlierDiff.SetBlocks(removedBlocks); } BlockInfoContiguous[] earlierBlocks = (earlierDiff == null ? new BlockInfoContiguous [] { } : earlierDiff.GetBlocks()); // Find later snapshot (or file itself) with blocks BlockInfoContiguous[] laterBlocks = FindLaterSnapshotBlocks(removed.GetSnapshotId ()); laterBlocks = (laterBlocks == null) ? file.GetBlocks() : laterBlocks; // Skip blocks, which belong to either the earlier or the later lists int i = 0; for (; i < removedBlocks.Length; i++) { if (i < earlierBlocks.Length && removedBlocks[i] == earlierBlocks[i]) { continue; } if (i < laterBlocks.Length && removedBlocks[i] == laterBlocks[i]) { continue; } break; } // Check if last block is part of truncate recovery BlockInfoContiguous lastBlock = file.GetLastBlock(); Block dontRemoveBlock = null; if (lastBlock != null && lastBlock.GetBlockUCState().Equals(HdfsServerConstants.BlockUCState .UnderRecovery)) { dontRemoveBlock = ((BlockInfoContiguousUnderConstruction)lastBlock).GetTruncateBlock (); } // Collect the remaining blocks of the file, ignoring truncate block for (; i < removedBlocks.Length; i++) { if (dontRemoveBlock == null || !removedBlocks[i].Equals(dontRemoveBlock)) { collectedBlocks.AddDeleteBlock(removedBlocks[i]); } } }
public virtual QuotaCounts UpdateQuotaAndCollectBlocks(BlockStoragePolicySuite bsps , INodeFile file, FileDiff removed, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { long oldStoragespace = file.StoragespaceConsumed(); byte storagePolicyID = file.GetStoragePolicyID(); BlockStoragePolicy bsp = null; EnumCounters <StorageType> typeSpaces = new EnumCounters <StorageType>(typeof(StorageType )); if (storagePolicyID != BlockStoragePolicySuite.IdUnspecified) { bsp = bsps.GetPolicy(file.GetStoragePolicyID()); } if (removed.snapshotINode != null) { short replication = removed.snapshotINode.GetFileReplication(); short currentRepl = file.GetBlockReplication(); if (currentRepl == 0) { long oldFileSizeNoRep = file.ComputeFileSize(true, true); oldStoragespace = oldFileSizeNoRep * replication; if (bsp != null) { IList <StorageType> oldTypeChosen = bsp.ChooseStorageTypes(replication); foreach (StorageType t in oldTypeChosen) { if (t.SupportTypeQuota()) { typeSpaces.Add(t, -oldFileSizeNoRep); } } } } else { if (replication > currentRepl) { long oldFileSizeNoRep = file.StoragespaceConsumedNoReplication(); oldStoragespace = oldFileSizeNoRep * replication; if (bsp != null) { IList <StorageType> oldTypeChosen = bsp.ChooseStorageTypes(replication); foreach (StorageType t in oldTypeChosen) { if (t.SupportTypeQuota()) { typeSpaces.Add(t, -oldFileSizeNoRep); } } IList <StorageType> newTypeChosen = bsp.ChooseStorageTypes(currentRepl); foreach (StorageType t_1 in newTypeChosen) { if (t_1.SupportTypeQuota()) { typeSpaces.Add(t_1, oldFileSizeNoRep); } } } } } AclFeature aclFeature = removed.GetSnapshotINode().GetAclFeature(); if (aclFeature != null) { AclStorage.RemoveAclFeature(aclFeature); } } GetDiffs().CombineAndCollectSnapshotBlocks(bsps, file, removed, collectedBlocks, removedINodes); long ssDelta = oldStoragespace - file.StoragespaceConsumed(); return(new QuotaCounts.Builder().StorageSpace(ssDelta).TypeSpaces(typeSpaces).Build ()); }
public _Processor_218(BlockStoragePolicySuite bsps, QuotaCounts counts, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { this.bsps = bsps; this.counts = counts; this.collectedBlocks = collectedBlocks; this.removedINodes = removedINodes; }
/// <summary>Delete and clear self.</summary> /// <param name="bsps">The block storage policy suite used to retrieve storage policy /// </param> /// <param name="currentINode">The inode where the deletion happens.</param> /// <param name="collectedBlocks">Used to collect blocks for deletion.</param> /// <param name="removedINodes">INodes removed</param> /// <returns>quota usage delta</returns> internal abstract QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite bsps, N currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes );
/// <summary>Combine the posterior diff and collect blocks for deletion.</summary> internal abstract QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite bsps, N currentINode, D posterior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes);
public virtual QuotaCounts CleanDirectory(BlockStoragePolicySuite bsps, INodeDirectory currentINode, int snapshot, int prior, INode.BlocksMapUpdateInfo collectedBlocks , IList <INode> removedINodes) { QuotaCounts counts = new QuotaCounts.Builder().Build(); IDictionary <INode, INode> priorCreated = null; IDictionary <INode, INode> priorDeleted = null; if (snapshot == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId) { // delete the current directory currentINode.RecordModification(prior); // delete everything in created list DirectoryWithSnapshotFeature.DirectoryDiff lastDiff = diffs.GetLast(); if (lastDiff != null) { counts.Add(lastDiff.diff.DestroyCreatedList(bsps, currentINode, collectedBlocks, removedINodes)); } counts.Add(currentINode.CleanSubtreeRecursively(bsps, snapshot, prior, collectedBlocks , removedINodes, priorDeleted)); } else { // update prior prior = GetDiffs().UpdatePrior(snapshot, prior); // if there is a snapshot diff associated with prior, we need to record // its original created and deleted list before deleting post if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId) { DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = this.GetDiffs().GetDiffById (prior); if (priorDiff != null && priorDiff.GetSnapshotId() == prior) { IList <INode> cList = priorDiff.diff.GetList(Diff.ListType.Created); IList <INode> dList = priorDiff.diff.GetList(Diff.ListType.Deleted); priorCreated = CloneDiffList(cList); priorDeleted = CloneDiffList(dList); } } counts.Add(GetDiffs().DeleteSnapshotDiff(bsps, snapshot, prior, currentINode, collectedBlocks , removedINodes)); counts.Add(currentINode.CleanSubtreeRecursively(bsps, snapshot, prior, collectedBlocks , removedINodes, priorDeleted)); // check priorDiff again since it may be created during the diff deletion if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId) { DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = this.GetDiffs().GetDiffById (prior); if (priorDiff != null && priorDiff.GetSnapshotId() == prior) { // For files/directories created between "prior" and "snapshot", // we need to clear snapshot copies for "snapshot". Note that we must // use null as prior in the cleanSubtree call. Files/directories that // were created before "prior" will be covered by the later // cleanSubtreeRecursively call. if (priorCreated != null) { // we only check the node originally in prior's created list foreach (INode cNode in priorDiff.GetChildrenDiff().GetList(Diff.ListType.Created )) { if (priorCreated.Contains(cNode)) { counts.Add(cNode.CleanSubtree(bsps, snapshot, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .NoSnapshotId, collectedBlocks, removedINodes)); } } } // When a directory is moved from the deleted list of the posterior // diff to the deleted list of this diff, we need to destroy its // descendants that were 1) created after taking this diff and 2) // deleted after taking posterior diff. // For files moved from posterior's deleted list, we also need to // delete its snapshot copy associated with the posterior snapshot. foreach (INode dNode in priorDiff.GetChildrenDiff().GetList(Diff.ListType.Deleted )) { if (priorDeleted == null || !priorDeleted.Contains(dNode)) { counts.Add(CleanDeletedINode(bsps, dNode, snapshot, prior, collectedBlocks, removedINodes )); } } } } } if (currentINode.IsQuotaSet()) { currentINode.GetDirectoryWithQuotaFeature().AddSpaceConsumed2Cache(counts.Negation ()); } return(counts); }
internal override QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite bsps, INodeDirectory currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { // this diff has been deleted QuotaCounts counts = new QuotaCounts.Builder().Build(); counts.Add(diff.DestroyDeletedList(bsps, collectedBlocks, removedINodes)); INodeDirectoryAttributes snapshotINode = GetSnapshotINode(); if (snapshotINode != null && snapshotINode.GetAclFeature() != null) { AclStorage.RemoveAclFeature(snapshotINode.GetAclFeature()); } return(counts); }
/// <summary> /// Clean an inode while we move it from the deleted list of post to the /// deleted list of prior. /// </summary> /// <param name="bsps">The block storage policy suite.</param> /// <param name="inode">The inode to clean.</param> /// <param name="post">The post snapshot.</param> /// <param name="prior">The id of the prior snapshot.</param> /// <param name="collectedBlocks">Used to collect blocks for later deletion.</param> /// <returns>Quota usage update.</returns> private static QuotaCounts CleanDeletedINode(BlockStoragePolicySuite bsps, INode inode, int post, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode > removedINodes) { QuotaCounts counts = new QuotaCounts.Builder().Build(); Deque <INode> queue = new ArrayDeque <INode>(); queue.AddLast(inode); while (!queue.IsEmpty()) { INode topNode = queue.PollFirst(); if (topNode is INodeReference.WithName) { INodeReference.WithName wn = (INodeReference.WithName)topNode; if (wn.GetLastSnapshotId() >= post) { wn.CleanSubtree(bsps, post, prior, collectedBlocks, removedINodes); } } else { // For DstReference node, since the node is not in the created list of // prior, we should treat it as regular file/dir if (topNode.IsFile() && topNode.AsFile().IsWithSnapshot()) { INodeFile file = topNode.AsFile(); counts.Add(file.GetDiffs().DeleteSnapshotDiff(bsps, post, prior, file, collectedBlocks , removedINodes)); } else { if (topNode.IsDirectory()) { INodeDirectory dir = topNode.AsDirectory(); DirectoryWithSnapshotFeature.ChildrenDiff priorChildrenDiff = null; DirectoryWithSnapshotFeature sf = dir.GetDirectoryWithSnapshotFeature(); if (sf != null) { // delete files/dirs created after prior. Note that these // files/dirs, along with inode, were deleted right after post. DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = sf.GetDiffs().GetDiffById( prior); if (priorDiff != null && priorDiff.GetSnapshotId() == prior) { priorChildrenDiff = priorDiff.GetChildrenDiff(); counts.Add(priorChildrenDiff.DestroyCreatedList(bsps, dir, collectedBlocks, removedINodes )); } } foreach (INode child in dir.GetChildrenList(prior)) { if (priorChildrenDiff != null && priorChildrenDiff.Search(Diff.ListType.Deleted, child.GetLocalNameBytes()) != null) { continue; } queue.AddLast(child); } } } } } return(counts); }
/// <summary>Destroy a subtree under a DstReference node.</summary> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> public static void DestroyDstSubtree(BlockStoragePolicySuite bsps, INode inode, int snapshot, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes ) { Preconditions.CheckArgument(prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .NoSnapshotId); if (inode.IsReference()) { if (inode is INodeReference.WithName && snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId) { // this inode has been renamed before the deletion of the DstReference // subtree inode.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes); } else { // for DstReference node, continue this process to its subtree DestroyDstSubtree(bsps, inode.AsReference().GetReferredINode(), snapshot, prior, collectedBlocks, removedINodes); } } else { if (inode.IsFile()) { inode.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes); } else { if (inode.IsDirectory()) { IDictionary <INode, INode> excludedNodes = null; INodeDirectory dir = inode.AsDirectory(); DirectoryWithSnapshotFeature sf = dir.GetDirectoryWithSnapshotFeature(); if (sf != null) { DirectoryWithSnapshotFeature.DirectoryDiffList diffList = sf.GetDiffs(); DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = diffList.GetDiffById(prior ); if (priorDiff != null && priorDiff.GetSnapshotId() == prior) { IList <INode> dList = priorDiff.diff.GetList(Diff.ListType.Deleted); excludedNodes = CloneDiffList(dList); } if (snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId) { diffList.DeleteSnapshotDiff(bsps, snapshot, prior, dir, collectedBlocks, removedINodes ); } priorDiff = diffList.GetDiffById(prior); if (priorDiff != null && priorDiff.GetSnapshotId() == prior) { priorDiff.diff.DestroyCreatedList(bsps, dir, collectedBlocks, removedINodes); } } foreach (INode child in inode.AsDirectory().GetChildrenList(prior)) { if (excludedNodes != null && excludedNodes.Contains(child)) { continue; } DestroyDstSubtree(bsps, child, snapshot, prior, collectedBlocks, removedINodes); } } } } }