You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by dh...@apache.org on 2008/03/13 20:52:15 UTC

svn commit: r636853 - in /hadoop/core/trunk: CHANGES.txt src/java/org/apache/hadoop/dfs/FSDirectory.java src/java/org/apache/hadoop/dfs/INode.java

Author: dhruba
Date: Thu Mar 13 12:52:13 2008
New Revision: 636853

URL: http://svn.apache.org/viewvc?rev=636853&view=rev
Log:
HADOOP-2423.  Code optimization in FSNamesystem.mkdirs.
(Tsz Wo (Nicholas), SZE via dhruba)


Modified:
    hadoop/core/trunk/CHANGES.txt
    hadoop/core/trunk/src/java/org/apache/hadoop/dfs/FSDirectory.java
    hadoop/core/trunk/src/java/org/apache/hadoop/dfs/INode.java

Modified: hadoop/core/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/CHANGES.txt?rev=636853&r1=636852&r2=636853&view=diff
==============================================================================
--- hadoop/core/trunk/CHANGES.txt (original)
+++ hadoop/core/trunk/CHANGES.txt Thu Mar 13 12:52:13 2008
@@ -97,6 +97,9 @@
     HADOOP-2399. Input key and value to combiner and reducer is reused.
     (Owen O'Malley via ddas). 
 
+    HADOOP-2423.  Code optimization in FSNamesystem.mkdirs.
+    (Tsz Wo (Nicholas), SZE via dhruba)
+
   BUG FIXES
 
     HADOOP-2195. '-mkdir' behaviour is now closer to Linux shell in case of

Modified: hadoop/core/trunk/src/java/org/apache/hadoop/dfs/FSDirectory.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/java/org/apache/hadoop/dfs/FSDirectory.java?rev=636853&r1=636852&r2=636853&view=diff
==============================================================================
--- hadoop/core/trunk/src/java/org/apache/hadoop/dfs/FSDirectory.java (original)
+++ hadoop/core/trunk/src/java/org/apache/hadoop/dfs/FSDirectory.java Thu Mar 13 12:52:13 2008
@@ -636,50 +636,39 @@
   boolean mkdirs(String src, PermissionStatus permissions,
       boolean inheritPermission, long now) throws IOException {
     src = normalizePath(src);
+    String[] names = INode.getPathNames(src);
+    byte[][] components = INode.getPathComponents(names);
 
-    // Use this to collect all the dirs we need to construct
-    List<String> v = new ArrayList<String>();
+    synchronized(rootDir) {
+      INode[] inodes = new INode[components.length];
+      rootDir.getExistingPathINodes(components, inodes);
 
-    // The dir itself
-    v.add(src);
+      // find the index of the first null in inodes[]  
+      StringBuilder pathbuilder = new StringBuilder();
+      int i = 1;
+      for(; i < inodes.length && inodes[i] != null; i++) {
+        pathbuilder.append(Path.SEPARATOR + names[i]);
+        if (!inodes[i].isDirectory()) {
+          throw new FileNotFoundException("Parent path is not a directory: "
+              + pathbuilder);
+        }
+      }
 
-    // All its parents
-    Path parent = new Path(src).getParent();
-    while (parent != null) {
-      v.add(parent.toString());
-      parent = parent.getParent();
-    }
+      // create directories beginning from the first null index
+      for(; i < inodes.length; i++) {
+        pathbuilder.append(Path.SEPARATOR + names[i]);
+        String cur = pathbuilder.toString();
+  
+        inodes[i] = new INodeDirectory(permissions, now);
+        inodes[i].name = components[i];
+        INode inserted = ((INodeDirectory)inodes[i-1]).addChild(
+            inodes[i], inheritPermission || i != inodes.length-1);
 
-    // Now go backwards through list of dirs, creating along
-    // the way
-    int numElts = v.size();
-    for (int i = numElts - 1; i >= 0; i--) {
-      String cur = v.get(i);
-      try {
-        INode inserted = null;
-        synchronized (rootDir) {
-          inserted = rootDir.addNode(cur, 
-                             new INodeDirectory(permissions, now),
-                             inheritPermission || i != 0);
-          if (inserted != null) {
-            totalInodes++;
-          }
-        }
-        if (inserted != null) {
-          NameNode.stateChangeLog.debug("DIR* FSDirectory.mkdirs: "
-                                        +"created directory "+cur);
-          fsImage.getEditLog().logMkDir(cur, inserted);
-        } else { // otherwise cur exists, verify that it is a directory
-          if (!isDir(cur)) {
-            NameNode.stateChangeLog.debug("DIR* FSDirectory.mkdirs: "
-                                          +"path " + cur + " is not a directory ");
-            return false;
-          } 
-        }
-      } catch (FileNotFoundException e) {
-        NameNode.stateChangeLog.debug("DIR* FSDirectory.mkdirs: "
-                                      +"failed to create directory "+src);
-        return false;
+        assert inserted == inodes[i];
+        totalInodes++;
+        NameNode.stateChangeLog.debug(
+            "DIR* FSDirectory.mkdirs: created directory " + cur);
+        fsImage.getEditLog().logMkDir(cur, inserted);
       }
     }
     return true;

Modified: hadoop/core/trunk/src/java/org/apache/hadoop/dfs/INode.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/java/org/apache/hadoop/dfs/INode.java?rev=636853&r1=636852&r2=636853&view=diff
==============================================================================
--- hadoop/core/trunk/src/java/org/apache/hadoop/dfs/INode.java (original)
+++ hadoop/core/trunk/src/java/org/apache/hadoop/dfs/INode.java Thu Mar 13 12:52:13 2008
@@ -232,21 +232,32 @@
    * a single path component.
    */
   static byte[][] getPathComponents(String path) {
-    if (path == null || !path.startsWith(Path.SEPARATOR)) {
-      return null;
-    }
-    if (Path.SEPARATOR.equals(path))  // root
+    return getPathComponents(getPathNames(path));
+  }
+
+  /** Convert strings to byte arrays for path components. */
+  static byte[][] getPathComponents(String[] strings) {
+    if (strings.length == 0) {
       return new byte[][]{null};
-    String[] strings = path.split(Path.SEPARATOR, -1);
-    int size = strings.length;
-    byte[][] bytes = new byte[size][];
-    for (int i = 0; i < size; i++)
+    }
+    byte[][] bytes = new byte[strings.length][];
+    for (int i = 0; i < strings.length; i++)
       bytes[i] = string2Bytes(strings[i]);
     return bytes;
   }
 
   /**
+   * Breaks file path into names.
+   * @param path
+   * @return array of names 
    */
+  static String[] getPathNames(String path) {
+    if (path == null || !path.startsWith(Path.SEPARATOR)) {
+      return null;
+    }
+    return path.split(Path.SEPARATOR);
+  }
+
   boolean removeNode() {
     if (parent == null) {
       return false;
@@ -423,7 +434,7 @@
    * @param existing INode array to fill with existing INodes
    * @return number of existing INodes in the path
    */
-  private int getExistingPathINodes(byte[][] components, INode[] existing) {
+  int getExistingPathINodes(byte[][] components, INode[] existing) {
     assert compareBytes(this.name, components[0]) == 0 :
       "Incorrect name " + getLocalName() + " expected " + components[0];
 
@@ -469,10 +480,21 @@
    * Add a child inode to the directory.
    * 
    * @param node INode to insert
+   * @param inheritPermission inherit permission from parent?
    * @return  null if the child with this name already exists; 
    *          inserted INode, otherwise
    */
-  private <T extends INode> T addChild(T node) {
+  <T extends INode> T addChild(final T node, boolean inheritPermission) {
+    if (inheritPermission) {
+      FsPermission p = getFsPermission();
+      //make sure the  permission has wx for the user
+      if (!p.getUserAction().implies(FsAction.WRITE_EXECUTE)) {
+        p = new FsPermission(p.getUserAction().or(FsAction.WRITE_EXECUTE),
+            p.getGroupAction(), p.getOtherAction());
+      }
+      node.setPermission(p);
+    }
+
     if (children == null) {
       children = new ArrayList<INode>(DEFAULT_FILES_PER_DIRECTORY);
     }
@@ -523,21 +545,10 @@
     if (!node.isDirectory()) {
       throw new FileNotFoundException("Parent path is not a directory: "+path);
     }
-    INodeDirectory parentNode = (INodeDirectory)node;
-
-    if (inheritPermission) {
-      FsPermission p = parentNode.getFsPermission();
-      //make sure the  permission has wx for the user
-      if (!p.getUserAction().implies(FsAction.WRITE_EXECUTE)) {
-        p = new FsPermission(p.getUserAction().or(FsAction.WRITE_EXECUTE),
-            p.getGroupAction(), p.getOtherAction());
-      }
-      newNode.setPermission(p);
-    }
 
     // insert into the parent children list
     newNode.name = pathComponents[pathLen-1];
-    return parentNode.addChild(newNode);
+    return ((INodeDirectory)node).addChild(newNode, inheritPermission);
   }
 
   /**