Browse Source

HDFS-4407. Change INodeDirectoryWithSnapshot.Diff.combinePostDiff(..) to merge-sort like and keep the postDiff parameter unmodified.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2802@1433918 13f79535-47bb-0310-9956-ffa450edef68
Tsz-wo Sze 12 years ago
parent
commit
7856221d4a

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt

@@ -106,3 +106,6 @@ Branch-2802 Snapshot (Unreleased)
 
 
   HDFS-4397. Fix a bug in INodeDirectoryWithSnapshot.Diff.combinePostDiff(..)
   HDFS-4397. Fix a bug in INodeDirectoryWithSnapshot.Diff.combinePostDiff(..)
   that it may put the wrong node into the deleted list.  (szetszwo)
   that it may put the wrong node into the deleted list.  (szetszwo)
+
+  HDFS-4407. Change INodeDirectoryWithSnapshot.Diff.combinePostDiff(..) to
+  merge-sort like and keep the postDiff parameter unmodified.  (szetszwo)

+ 27 - 16
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectoryWithSnapshot.java

@@ -330,28 +330,39 @@ public class INodeDirectoryWithSnapshot extends INodeDirectoryWithQuota {
      *                              to process the deleted inodes.
      *                              to process the deleted inodes.
      */
      */
     void combinePostDiff(Diff postDiff, Processor deletedINodeProcesser) {
     void combinePostDiff(Diff postDiff, Processor deletedINodeProcesser) {
-      while (postDiff.created != null && !postDiff.created.isEmpty()) {
-        final INode c = postDiff.created.remove(postDiff.created.size() - 1);
-        final int deletedIndex = search(postDiff.deleted, c);
-        if (deletedIndex < 0) {
-          // case 1
+      final List<INode> postCreated = postDiff.created != null?
+          postDiff.created: Collections.<INode>emptyList();
+      final List<INode> postDeleted = postDiff.deleted != null?
+          postDiff.deleted: Collections.<INode>emptyList();
+      final Iterator<INode> createdIterator = postCreated.iterator();
+      final Iterator<INode> deletedIterator = postDeleted.iterator();
+
+      INode c = createdIterator.hasNext()? createdIterator.next(): null;
+      INode d = deletedIterator.hasNext()? deletedIterator.next(): null;
+
+      for(; c != null || d != null; ) {
+        final int cmp = c == null? 1
+            : d == null? -1
+            : c.compareTo(d.getLocalNameBytes());
+        if (cmp < 0) {
+          // case 1: only in c-list
           create(c);
           create(c);
+          c = createdIterator.hasNext()? createdIterator.next(): null;
+        } else if (cmp > 0) {
+          // case 2: only in d-list
+          Triple<Integer, INode, Integer> triple = delete(d);
+          if (deletedINodeProcesser != null) {
+            deletedINodeProcesser.process(triple.middle);
+          }
+          d = deletedIterator.hasNext()? deletedIterator.next(): null;
         } else {
         } else {
-          final INode d = postDiff.deleted.remove(deletedIndex);
-          // case 3
+          // case 3: in both c-list and d-list 
           final Triple<Integer, INode, Integer> triple = modify(d, c);
           final Triple<Integer, INode, Integer> triple = modify(d, c);
           if (deletedINodeProcesser != null) {
           if (deletedINodeProcesser != null) {
             deletedINodeProcesser.process(triple.middle);
             deletedINodeProcesser.process(triple.middle);
           }
           }
-        }
-      }
-      
-      while (postDiff.deleted != null && !postDiff.deleted.isEmpty()) {
-        // case 2
-        INode node = postDiff.deleted.remove(postDiff.deleted.size() - 1);
-        Triple<Integer, INode, Integer> triple = delete(node);
-        if (deletedINodeProcesser != null) {
-          deletedINodeProcesser.process(triple.middle);
+          c = createdIterator.hasNext()? createdIterator.next(): null;
+          d = deletedIterator.hasNext()? deletedIterator.next(): null;
         }
         }
       }
       }
     }
     }