hadoop-hdfs-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From szets...@apache.org
Subject svn commit: r1407703 - in /hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs: ./ src/main/java/org/apache/hadoop/hdfs/server/namenode/ src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/ src/test/java/org/apache/hadoop/hdfs/se...
Date Sat, 10 Nov 2012 00:28:00 GMT
Author: szetszwo
Date: Sat Nov 10 00:27:59 2012
New Revision: 1407703

URL: http://svn.apache.org/viewvc?rev=1407703&view=rev
Log:
HDFS-4170. Add snapshot information to INodesInPath.

Modified:
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectorySnapshottable.java
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/Snapshot.java
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java
    hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/CHANGES.HDFS-2802.txt
Sat Nov 10 00:27:59 2012
@@ -62,3 +62,5 @@ Branch-2802 Snapshot (Unreleased)
 
   HDFS-4159. Rename should fail when the destination directory is snapshottable
   and has snapshots. (Jing Zhao via szetszwo)
+
+  HDFS-4170. Add snapshot information to INodesInPath.  (szetszwo)

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java
Sat Nov 10 00:27:59 2012
@@ -32,6 +32,7 @@ import org.apache.hadoop.hdfs.protocol.H
 import org.apache.hadoop.hdfs.protocol.UnresolvedPathException;
 import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectorySnapshottable;
 import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectoryWithSnapshot;
+import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
 
 import com.google.common.annotations.VisibleForTesting;
 
@@ -212,6 +213,13 @@ public class INodeDirectory extends INod
       if (index >= 0) {
         existing.addNode(curNode);
       }
+      if (curNode instanceof INodeDirectorySnapshottable) {
+        //if the path is a non-snapshot path, update the latest snapshot.
+        if (!existing.isSnapshot()) {
+          existing.updateLatestSnapshot(
+              ((INodeDirectorySnapshottable)curNode).getLastSnapshot());
+        }
+      }
       if (curNode.isSymlink() && (!lastComp || (lastComp && resolveLink)))
{
         final String path = constructPath(components, 0, components.length);
         final String preceding = constructPath(components, 0, count);
@@ -247,10 +255,17 @@ public class INodeDirectory extends INod
           return existing;
         }
         // Resolve snapshot root
-        curNode = ((INodeDirectorySnapshottable) parentDir)
-            .getSnapshotRoot(components[count + 1]);
+        final Snapshot s = ((INodeDirectorySnapshottable)parentDir).getSnapshot(
+            components[count + 1]);
+        if (s == null) {
+          //snapshot not found
+          curNode = null;
+        } else {
+          curNode = s.getRoot();
+          existing.setSnapshot(s);
+        }
         if (index >= -1) {
-          existing.snapshotRootIndex = existing.size;
+          existing.snapshotRootIndex = existing.numNonNull;
         }
       } else {
         // normal case, and also for resolving file/dir under snapshot root
@@ -498,7 +513,7 @@ public class INodeDirectory extends INod
     /**
      * Indicate the number of non-null elements in {@link #inodes}
      */
-    private int size;
+    private int numNonNull;
     /**
      * The path for a snapshot file/dir contains the .snapshot thus makes the
      * length of the path components larger the number of inodes. We use
@@ -513,17 +528,41 @@ public class INodeDirectory extends INod
      * Index of {@link INodeDirectoryWithSnapshot} for snapshot path, else -1
      */
     private int snapshotRootIndex;
+    /**
+     * For snapshot paths, it is the reference to the snapshot; or null if the
+     * snapshot does not exist. For non-snapshot paths, it is the reference to
+     * the latest snapshot found in the path; or null if no snapshot is found.
+     */
+    private Snapshot snapshot = null; 
 
     INodesInPath(int number) {
       assert (number >= 0);
       inodes = new INode[number];
       capacity = number;
-      size = 0;
+      numNonNull = 0;
       isSnapshot = false;
       snapshotRootIndex = -1;
     }
 
     /**
+     * @return the snapshot associated to the path.
+     * @see #snapshot
+     */
+    public Snapshot getSnapshot() {
+      return snapshot;
+    }
+
+    private void setSnapshot(Snapshot s) {
+      snapshot = s;
+    }
+    
+    private void updateLatestSnapshot(Snapshot s) {
+      if (snapshot == null || snapshot.compareTo(s) < 0) {
+        snapshot = s;
+      }
+    }
+
+    /**
      * @return the whole inodes array including the null elements.
      */
     INode[] getINodes() {
@@ -556,8 +595,7 @@ public class INodeDirectory extends INod
      * Add an INode at the end of the array
      */
     private void addNode(INode node) {
-      assert size < inodes.length;
-      inodes[size++] = node;
+      inodes[numNonNull++] = node;
     }
     
     void setINode(int i, INode inode) {
@@ -567,8 +605,35 @@ public class INodeDirectory extends INod
     /**
      * @return The number of non-null elements
      */
-    int getSize() {
-      return size;
+    int getNumNonNull() {
+      return numNonNull;
+    }
+    
+    static String toString(INode inode) {
+      return inode == null? null: inode.getLocalName();
+    }
+
+    @Override
+    public String toString() {
+      final StringBuilder b = new StringBuilder(getClass().getSimpleName())
+          .append(":\n  inodes = ");
+      if (inodes == null) {
+        b.append("null");
+      } else if (inodes.length == 0) {
+        b.append("[]");
+      } else {
+        b.append("[").append(toString(inodes[0]));
+        for(int i = 1; i < inodes.length; i++) {
+          b.append(", ").append(toString(inodes[i]));
+        }
+        b.append("]");
+      }
+      b.append("\n  numNonNull = ").append(numNonNull)
+       .append("\n  capacity   = ").append(capacity)
+       .append("\n  isSnapshot        = ").append(isSnapshot)
+       .append("\n  snapshotRootIndex = ").append(snapshotRootIndex)
+       .append("\n  snapshot          = ").append(snapshot);
+      return b.toString();
     }
   }
 

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectorySnapshottable.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectorySnapshottable.java?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectorySnapshottable.java
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/INodeDirectorySnapshottable.java
Sat Nov 10 00:27:59 2012
@@ -65,6 +65,8 @@ public class INodeDirectorySnapshottable
 
   /** Snapshots of this directory in ascending order of snapshot id. */
   private final List<Snapshot> snapshots = new ArrayList<Snapshot>();
+  /** Snapshots of this directory in ascending order of snapshot names. */
+  private final List<Snapshot> snapshotsByNames = new ArrayList<Snapshot>();
 
   /** Number of snapshots allowed. */
   private int snapshotQuota;
@@ -79,16 +81,20 @@ public class INodeDirectorySnapshottable
     return snapshots.size();
   }
   
-  /** @return the root directory of a snapshot. */
-  public INodeDirectory getSnapshotRoot(byte[] snapshotName) {
-    if (snapshots == null || snapshots.size() == 0) {
-      return null;
-    }
-    int low = Collections.binarySearch(snapshots, snapshotName);
-    if (low >= 0) {
-      return snapshots.get(low).getRoot();
-    }
-    return null;
+  private int searchSnapshot(byte[] snapshotName) {
+    return Collections.binarySearch(snapshotsByNames, snapshotName);
+  }
+
+  /** @return the snapshot with the given name. */
+  public Snapshot getSnapshot(byte[] snapshotName) {
+    final int i = searchSnapshot(snapshotName);
+    return i < 0? null: snapshotsByNames.get(i);
+  }
+
+  /** @return the last snapshot. */
+  public Snapshot getLastSnapshot() {
+    final int n = snapshots.size();
+    return n == 0? null: snapshots.get(n - 1);
   }
 
   public int getSnapshotQuota() {
@@ -108,21 +114,30 @@ public class INodeDirectorySnapshottable
     return true;
   }
 
-  /** Add a snapshot root under this directory. */
-  void addSnapshot(final Snapshot s) throws SnapshotException {
+  /** Add a snapshot. */
+  Snapshot addSnapshot(int id, String name) throws SnapshotException {
     //check snapshot quota
     if (snapshots.size() + 1 > snapshotQuota) {
       throw new SnapshotException("Failed to add snapshot: there are already "
           + snapshots.size() + " snapshot(s) and the snapshot quota is "
           + snapshotQuota);
     }
+    final Snapshot s = new Snapshot(id, name, this);
+    final byte[] nameBytes = s.getRoot().getLocalNameBytes();
+    final int i = searchSnapshot(nameBytes);
+    if (i >= 0) {
+      throw new SnapshotException("Failed to add snapshot: there is already a "
+          + "snapshot with the same name \"" + name + "\".");
+    }
 
     snapshots.add(s);
+    snapshotsByNames.add(-i - 1, s);
 
     //set modification time
     final long timestamp = Time.now();
     s.getRoot().setModificationTime(timestamp);
     setModificationTime(timestamp);
+    return s;
   }
   
   @Override

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/Snapshot.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/Snapshot.java?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/Snapshot.java
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/Snapshot.java
Sat Nov 10 00:27:59 2012
@@ -32,7 +32,8 @@ public class Snapshot implements Compara
     this.root = new INodeDirectoryWithSnapshot(name, dir);
   }
 
-  INodeDirectoryWithSnapshot getRoot() {
+  /** @return the root directory of the snapshot. */
+  public INodeDirectoryWithSnapshot getRoot() {
     return root;
   }
 
@@ -40,4 +41,14 @@ public class Snapshot implements Compara
   public int compareTo(byte[] bytes) {
     return root.compareTo(bytes);
   }
+
+  /** Compare snapshot IDs. */
+  public int compareTo(Snapshot s) {
+    return id - s.id;
+  }
+  
+  @Override
+  public String toString() {
+    return getClass().getSimpleName() + ":" + root.getLocalName();
+  }
 }

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java
Sat Nov 10 00:27:59 2012
@@ -105,8 +105,7 @@ public class SnapshotManager implements 
         = INodeDirectorySnapshottable.valueOf(fsdir.getINode(path), path);
 
     synchronized(this) {
-      final Snapshot s = new Snapshot(snapshotID, snapshotName, srcRoot); 
-      srcRoot.addSnapshot(s);
+      final Snapshot s = srcRoot.addSnapshot(snapshotID, snapshotName);
       new SnapshotCreation().processRecursively(srcRoot, s.getRoot());
       
       //create success, update id

Modified: hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java?rev=1407703&r1=1407702&r2=1407703&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java
(original)
+++ hadoop/common/branches/HDFS-2802/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java
Sat Nov 10 00:27:59 2012
@@ -25,15 +25,17 @@ import static org.junit.Assert.assertTru
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hdfs.DFSTestUtil;
+import org.apache.hadoop.hdfs.DFSUtil;
 import org.apache.hadoop.hdfs.DistributedFileSystem;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.apache.hadoop.hdfs.server.namenode.INodeDirectory.INodesInPath;
-import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectoryWithSnapshot;
 import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectorySnapshottable;
+import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectoryWithSnapshot;
 import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeFileSnapshot;
-import org.junit.After;
+import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
+import org.junit.AfterClass;
 import org.junit.Assert;
-import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /** Test snapshot related operations. */
@@ -41,21 +43,21 @@ public class TestSnapshotPathINodes {
   private static final long seed = 0;
   private static final short REPLICATION = 3;
 
-  private final Path dir = new Path("/TestSnapshot");
+  static private final Path dir = new Path("/TestSnapshot");
   
-  private final Path sub1 = new Path(dir, "sub1");
-  private final Path file1 = new Path(sub1, "file1");
-  private final Path file2 = new Path(sub1, "file2");
-
-  private Configuration conf;
-  private MiniDFSCluster cluster;
-  private FSNamesystem fsn;
-  private FSDirectory fsdir;
+  static private final Path sub1 = new Path(dir, "sub1");
+  static private final Path file1 = new Path(sub1, "file1");
+  static private final Path file2 = new Path(sub1, "file2");
+
+  static private Configuration conf;
+  static private MiniDFSCluster cluster;
+  static private FSNamesystem fsn;
+  static private FSDirectory fsdir;
 
-  private DistributedFileSystem hdfs;
+  static private DistributedFileSystem hdfs;
 
-  @Before
-  public void setUp() throws Exception {
+  @BeforeClass
+  static public void setUp() throws Exception {
     conf = new Configuration();
     cluster = new MiniDFSCluster.Builder(conf)
       .numDataNodes(REPLICATION)
@@ -70,8 +72,8 @@ public class TestSnapshotPathINodes {
     DFSTestUtil.createFile(hdfs, file2, 1024, REPLICATION, seed);
   }
 
-  @After
-  public void tearDown() throws Exception {
+  @AfterClass
+  static public void tearDown() throws Exception {
     if (cluster != null) {
       cluster.shutdown();
     }
@@ -102,6 +104,23 @@ public class TestSnapshotPathINodes {
     }
   }
   
+  static Snapshot getSnapshot(INodesInPath inodesInPath, String name) {
+    if (name == null) {
+      return null;
+    }
+    final int i = inodesInPath.getSnapshotRootIndex() - 1;
+    final INode inode = inodesInPath.getINodes()[i];
+    return ((INodeDirectorySnapshottable)inode).getSnapshot(
+        DFSUtil.string2Bytes(name)); 
+  }
+
+  static void assertSnapshot(INodesInPath inodesInPath, boolean isSnapshot,
+      final Snapshot snapshot, int index) {
+    assertEquals(isSnapshot, inodesInPath.isSnapshot());
+    assertEquals(index, inodesInPath.getSnapshotRootIndex());
+    assertEquals(snapshot, inodesInPath.getSnapshot());
+  }
+
   /** 
    * Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)} 
    * for normal (non-snapshot) file.
@@ -117,8 +136,8 @@ public class TestSnapshotPathINodes {
     // The number of inodes should be equal to components.length
     assertEquals(inodes.length, components.length);
     // The returned nodesInPath should be non-snapshot
-    assertFalse(nodesInPath.isSnapshot());
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, false, null, -1);
+
     // The last INode should be associated with file1
     assertEquals(inodes[components.length - 1].getFullPathName(),
         file1.toString());
@@ -132,8 +151,7 @@ public class TestSnapshotPathINodes {
     nodesInPath = fsdir.rootDir.getExistingPathINodes(components, 1, false);
     inodes = nodesInPath.getINodes();
     assertEquals(inodes.length, 1);
-    assertFalse(nodesInPath.isSnapshot());
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, false, null, -1);
     assertEquals(inodes[0].getFullPathName(), file1.toString());
     
     // Call getExistingPathINodes and request 2 INodes. This is usually used
@@ -141,8 +159,7 @@ public class TestSnapshotPathINodes {
     nodesInPath = fsdir.rootDir.getExistingPathINodes(components, 2, false);
     inodes = nodesInPath.getINodes();
     assertEquals(inodes.length, 2);
-    assertFalse(nodesInPath.isSnapshot());
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, false, null, -1);
     assertEquals(inodes[1].getFullPathName(), file1.toString());
     assertEquals(inodes[0].getFullPathName(), sub1.toString());
   }
@@ -168,9 +185,9 @@ public class TestSnapshotPathINodes {
     // Length of inodes should be (components.length - 1), since we will ignore
     // ".snapshot" 
     assertEquals(inodes.length, components.length - 1);
-    assertTrue(nodesInPath.isSnapshot());
     // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s1, file1}
-    assertEquals(nodesInPath.getSnapshotRootIndex(), 3);
+    final Snapshot snapshot = getSnapshot(nodesInPath, "s1");
+    assertSnapshot(nodesInPath, true, snapshot, 3);
     assertTrue(inodes[nodesInPath.getSnapshotRootIndex()] instanceof 
         INodeDirectoryWithSnapshot);
     // Check the INode for file1 (snapshot file)
@@ -184,10 +201,9 @@ public class TestSnapshotPathINodes {
     nodesInPath = fsdir.rootDir.getExistingPathINodes(components, 1, false);
     inodes = nodesInPath.getINodes();
     assertEquals(inodes.length, 1);
-    assertTrue(nodesInPath.isSnapshot());
     // The snapshotroot (s1) is not included in inodes. Thus the
     // snapshotRootIndex should be -1.
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, true, snapshot, -1);
     // Check the INode for file1 (snapshot file)
     snapshotFileNode = inodes[inodes.length - 1]; 
     assertEquals(snapshotFileNode.getLocalName(), file1.getName());
@@ -197,10 +213,9 @@ public class TestSnapshotPathINodes {
     nodesInPath = fsdir.rootDir.getExistingPathINodes(components, 2, false);
     inodes = nodesInPath.getINodes();
     assertEquals(inodes.length, 2);
-    assertTrue(nodesInPath.isSnapshot());
     // There should be two INodes in inodes: s1 and snapshot of file1. Thus the
     // SnapshotRootIndex should be 0.
-    assertEquals(nodesInPath.getSnapshotRootIndex(), 0);
+    assertSnapshot(nodesInPath, true, snapshot, 0);
     snapshotFileNode = inodes[inodes.length - 1];
     // Check the INode for snapshot of file1
     assertEquals(snapshotFileNode.getLocalName(), file1.getName());
@@ -216,9 +231,9 @@ public class TestSnapshotPathINodes {
     // The number of INodes returned should be components.length - 1 since we
     // will ignore ".snapshot"
     assertEquals(inodes.length, components.length - 1);
-    assertTrue(nodesInPath.isSnapshot());
+
     // No SnapshotRoot dir is included in the resolved inodes  
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, true, snapshot, -1);
     // The last INode should be the INode for sub1
     assertEquals(inodes[inodes.length - 1].getFullPathName(), sub1.toString());
     assertFalse(inodes[inodes.length - 1] instanceof INodeFileSnapshot);
@@ -233,11 +248,38 @@ public class TestSnapshotPathINodes {
     // Create a snapshot for the dir, and check the inodes for the path
     // pointing to a snapshot file
     hdfs.allowSnapshot(sub1.toString());
-    hdfs.createSnapshot("s1", sub1.toString());
+    hdfs.createSnapshot("s2", sub1.toString());
     
     // Delete the original file /TestSnapshot/sub1/file1
     hdfs.delete(file1, false);
     
+    final Snapshot snapshot;
+    {
+      // Resolve the path for the snapshot file
+      // /TestSnapshot/sub1/.snapshot/s2/file1
+      String snapshotPath = sub1.toString() + "/.snapshot/s2/file1";
+      String[] names = INode.getPathNames(snapshotPath);
+      byte[][] components = INode.getPathComponents(names);
+      INodesInPath nodesInPath = fsdir.rootDir.getExistingPathINodes(components,
+          components.length, false);
+      INode[] inodes = nodesInPath.getINodes();
+      // Length of inodes should be (components.length - 1), since we will ignore
+      // ".snapshot" 
+      assertEquals(inodes.length, components.length - 1);
+      // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s2, file1}
+      snapshot = getSnapshot(nodesInPath, "s2");
+      assertSnapshot(nodesInPath, true, snapshot, 3);
+  
+      assertTrue(inodes[nodesInPath.getSnapshotRootIndex()] instanceof 
+          INodeDirectoryWithSnapshot);
+      // Check the INode for file1 (snapshot file)
+      INode snapshotFileNode = inodes[inodes.length - 1]; 
+      assertEquals(snapshotFileNode.getLocalName(), file1.getName());
+      assertTrue(snapshotFileNode instanceof INodeFileSnapshot);
+      assertTrue(snapshotFileNode.getParent() instanceof 
+          INodeDirectoryWithSnapshot);
+    }
+
     // Check the INodes for path /TestSnapshot/sub1/file1
     String[] names = INode.getPathNames(file1.toString());
     byte[][] components = INode.getPathComponents(names);
@@ -248,10 +290,9 @@ public class TestSnapshotPathINodes {
     assertEquals(inodes.length, components.length);
     // The number of non-null elements should be components.length - 1 since
     // file1 has been deleted
-    assertEquals(nodesInPath.getSize(), components.length - 1);
+    assertEquals(nodesInPath.getNumNonNull(), components.length - 1);
     // The returned nodesInPath should be non-snapshot
-    assertFalse(nodesInPath.isSnapshot());
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, false, snapshot, -1);
     // The last INode should be null, and the one before should be associated
     // with sub1
     assertNull(inodes[components.length - 1]);
@@ -259,31 +300,10 @@ public class TestSnapshotPathINodes {
         sub1.toString());
     assertEquals(inodes[components.length - 3].getFullPathName(),
         dir.toString());
-    
-    // Resolve the path for the snapshot file
-    // /TestSnapshot/sub1/.snapshot/s1/file1
-    String snapshotPath = sub1.toString() + "/.snapshot/s1/file1";
-    names = INode.getPathNames(snapshotPath);
-    components = INode.getPathComponents(names);
-    nodesInPath = fsdir.rootDir.getExistingPathINodes(components,
-        components.length, false);
-    inodes = nodesInPath.getINodes();
-    // Length of inodes should be (components.length - 1), since we will ignore
-    // ".snapshot" 
-    assertEquals(inodes.length, components.length - 1);
-    assertTrue(nodesInPath.isSnapshot());
-    // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s1, file1}
-    assertEquals(nodesInPath.getSnapshotRootIndex(), 3);
-    assertTrue(inodes[nodesInPath.getSnapshotRootIndex()] instanceof 
-        INodeDirectoryWithSnapshot);
-    // Check the INode for file1 (snapshot file)
-    INode snapshotFileNode = inodes[inodes.length - 1]; 
-    assertEquals(snapshotFileNode.getLocalName(), file1.getName());
-    assertTrue(snapshotFileNode instanceof INodeFileSnapshot);
-    assertTrue(snapshotFileNode.getParent() instanceof 
-        INodeDirectoryWithSnapshot);
   }
   
+  static private Snapshot s4;
+
   /** 
    * Test {@link INodeDirectory#getExistingPathINodes(byte[][], int, boolean)} 
    * for snapshot file while adding a new file after snapshot.
@@ -293,12 +313,39 @@ public class TestSnapshotPathINodes {
     // Create a snapshot for the dir, and check the inodes for the path
     // pointing to a snapshot file
     hdfs.allowSnapshot(sub1.toString());
-    hdfs.createSnapshot("s1", sub1.toString());
+    hdfs.createSnapshot("s4", sub1.toString());
     
     // Add a new file /TestSnapshot/sub1/file3
     final Path file3 = new Path(sub1, "file3");
     DFSTestUtil.createFile(hdfs, file3, 1024, REPLICATION, seed);
   
+    {
+      // Check the inodes for /TestSnapshot/sub1/.snapshot/s4/file3
+      String snapshotPath = sub1.toString() + "/.snapshot/s4/file3";
+      String[] names = INode.getPathNames(snapshotPath);
+      byte[][] components = INode.getPathComponents(names);
+      INodesInPath nodesInPath = fsdir.rootDir.getExistingPathINodes(components,
+          components.length, false);
+      INode[] inodes = nodesInPath.getINodes();
+      // Length of inodes should be (components.length - 1), since we will ignore
+      // ".snapshot" 
+      assertEquals(inodes.length, components.length - 1);
+      // The number of non-null inodes should be components.length - 2, since
+      // snapshot of file3 does not exist
+      assertEquals(nodesInPath.getNumNonNull(), components.length - 2);
+      s4 = getSnapshot(nodesInPath, "s4");
+
+      // SnapshotRootIndex should still be 3: {root, Testsnapshot, sub1, s4, null}
+      assertSnapshot(nodesInPath, true, s4, 3);
+  
+      assertTrue(inodes[nodesInPath.getSnapshotRootIndex()] instanceof 
+          INodeDirectoryWithSnapshot);
+      // Check the last INode in inodes, which should be null
+      assertNull(inodes[inodes.length - 1]);
+      assertTrue(inodes[inodes.length - 2] instanceof 
+          INodeDirectoryWithSnapshot);
+    }
+
     // Check the inodes for /TestSnapshot/sub1/file3
     String[] names = INode.getPathNames(file3.toString());
     byte[][] components = INode.getPathComponents(names);
@@ -307,9 +354,10 @@ public class TestSnapshotPathINodes {
     INode[] inodes = nodesInPath.getINodes();
     // The number of inodes should be equal to components.length
     assertEquals(inodes.length, components.length);
+
     // The returned nodesInPath should be non-snapshot
-    assertFalse(nodesInPath.isSnapshot());
-    assertEquals(nodesInPath.getSnapshotRootIndex(), -1);
+    assertSnapshot(nodesInPath, false, s4, -1);
+
     // The last INode should be associated with file3
     assertEquals(inodes[components.length - 1].getFullPathName(),
         file3.toString());
@@ -317,29 +365,6 @@ public class TestSnapshotPathINodes {
         sub1.toString());
     assertEquals(inodes[components.length - 3].getFullPathName(),
         dir.toString());
-    
-    // Check the inodes for /TestSnapshot/sub1/.snapshot/s1/file3
-    String snapshotPath = sub1.toString() + "/.snapshot/s1/file3";
-    names = INode.getPathNames(snapshotPath);
-    components = INode.getPathComponents(names);
-    nodesInPath = fsdir.rootDir.getExistingPathINodes(components,
-        components.length, false);
-    inodes = nodesInPath.getINodes();
-    // Length of inodes should be (components.length - 1), since we will ignore
-    // ".snapshot" 
-    assertEquals(inodes.length, components.length - 1);
-    // The number of non-null inodes should be components.length - 2, since
-    // snapshot of file3 does not exist
-    assertEquals(nodesInPath.getSize(), components.length - 2);
-    assertTrue(nodesInPath.isSnapshot());
-    // SnapshotRootIndex should still be 3: {root, Testsnapshot, sub1, s1, null}
-    assertEquals(nodesInPath.getSnapshotRootIndex(), 3);
-    assertTrue(inodes[nodesInPath.getSnapshotRootIndex()] instanceof 
-        INodeDirectoryWithSnapshot);
-    // Check the last INode in inodes, which should be null
-    assertNull(inodes[inodes.length - 1]);
-    assertTrue(inodes[inodes.length - 2] instanceof 
-        INodeDirectoryWithSnapshot);
   }
   
   /** 
@@ -348,6 +373,9 @@ public class TestSnapshotPathINodes {
    */
   @Test
   public void testSnapshotPathINodesAfterModification() throws Exception {
+    //file1 was deleted, create it again.
+    DFSTestUtil.createFile(hdfs, file1, 1024, REPLICATION, seed);
+
     // First check the INode for /TestSnapshot/sub1/file1
     String[] names = INode.getPathNames(file1.toString());
     byte[][] components = INode.getPathComponents(names);
@@ -356,6 +384,8 @@ public class TestSnapshotPathINodes {
     INode[] inodes = nodesInPath.getINodes();
     // The number of inodes should be equal to components.length
     assertEquals(inodes.length, components.length);
+    assertSnapshot(nodesInPath, false, s4, -1);
+
     // The last INode should be associated with file1
     assertEquals(inodes[components.length - 1].getFullPathName(),
         file1.toString());
@@ -363,25 +393,13 @@ public class TestSnapshotPathINodes {
     // Create a snapshot for the dir, and check the inodes for the path
     // pointing to a snapshot file
     hdfs.allowSnapshot(sub1.toString());
-    hdfs.createSnapshot("s1", sub1.toString());
+    hdfs.createSnapshot("s3", sub1.toString());
     
     // Modify file1
     DFSTestUtil.appendFile(hdfs, file1, "the content for appending");
-    // Check the INode for /TestSnapshot/sub1/file1 again
-    INodesInPath newNodesInPath = fsdir.rootDir
-        .getExistingPathINodes(components, components.length, false);
-    INode[] newInodes = newNodesInPath.getINodes();
-    // The number of inodes should be equal to components.length
-    assertEquals(newInodes.length, components.length);
-    // The last INode should be associated with file1
-    assertEquals(newInodes[components.length - 1].getFullPathName(),
-        file1.toString());
-    // The modification time of the INode for file3 should have been changed
-    Assert.assertFalse(inodes[components.length - 1].getModificationTime() ==
-        newInodes[components.length - 1].getModificationTime());
-    
+
     // Check the INodes for snapshot of file1
-    String snapshotPath = sub1.toString() + "/.snapshot/s1/file1";
+    String snapshotPath = sub1.toString() + "/.snapshot/s3/file1";
     names = INode.getPathNames(snapshotPath);
     components = INode.getPathComponents(names);
     INodesInPath ssNodesInPath = fsdir.rootDir.getExistingPathINodes(
@@ -390,7 +408,8 @@ public class TestSnapshotPathINodes {
     // Length of ssInodes should be (components.length - 1), since we will
     // ignore ".snapshot" 
     assertEquals(ssInodes.length, components.length - 1);
-    assertTrue(ssNodesInPath.isSnapshot());
+    final Snapshot s3 = getSnapshot(ssNodesInPath, "s3");
+    assertSnapshot(ssNodesInPath, true, s3, 3);
     // Check the INode for snapshot of file1
     INode snapshotFileNode = ssInodes[ssInodes.length - 1]; 
     assertEquals(snapshotFileNode.getLocalName(), file1.getName());
@@ -399,5 +418,21 @@ public class TestSnapshotPathINodes {
     // original INode before modification
     assertEquals(inodes[inodes.length - 1].getModificationTime(),
         ssInodes[ssInodes.length - 1].getModificationTime());
+
+    // Check the INode for /TestSnapshot/sub1/file1 again
+    names = INode.getPathNames(file1.toString());
+    components = INode.getPathComponents(names);
+    INodesInPath newNodesInPath = fsdir.rootDir
+        .getExistingPathINodes(components, components.length, false);
+    assertSnapshot(newNodesInPath, false, s3, -1);
+    INode[] newInodes = newNodesInPath.getINodes();
+    // The number of inodes should be equal to components.length
+    assertEquals(newInodes.length, components.length);
+    // The last INode should be associated with file1
+    assertEquals(newInodes[components.length - 1].getFullPathName(),
+        file1.toString());
+    // The modification time of the INode for file3 should have been changed
+    Assert.assertFalse(inodes[components.length - 1].getModificationTime() ==
+        newInodes[components.length - 1].getModificationTime());
   }
 }



Mime
View raw message