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);
}
/**