Skip to content

Commit 22ef528

Browse files
committed
HDFS-10674. Optimize creating a full path from an inode. Contributed by Daryn Sharp.
1 parent 58db263 commit 22ef528

File tree

5 files changed

+29
-59
lines changed

5 files changed

+29
-59
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -885,57 +885,6 @@ public EnumCounters<StorageType> getStorageTypeDeltas(byte storagePolicyID,
885885
return typeSpaceDeltas;
886886
}
887887

888-
/** Return the name of the path represented by inodes at [0, pos] */
889-
static String getFullPathName(INode[] inodes, int pos) {
890-
StringBuilder fullPathName = new StringBuilder();
891-
if (inodes[0].isRoot()) {
892-
if (pos == 0) return Path.SEPARATOR;
893-
} else {
894-
fullPathName.append(inodes[0].getLocalName());
895-
}
896-
897-
for (int i=1; i<=pos; i++) {
898-
fullPathName.append(Path.SEPARATOR_CHAR).append(inodes[i].getLocalName());
899-
}
900-
return fullPathName.toString();
901-
}
902-
903-
/**
904-
* @return the relative path of an inode from one of its ancestors,
905-
* represented by an array of inodes.
906-
*/
907-
private static INode[] getRelativePathINodes(INode inode, INode ancestor) {
908-
// calculate the depth of this inode from the ancestor
909-
int depth = 0;
910-
for (INode i = inode; i != null && !i.equals(ancestor); i = i.getParent()) {
911-
depth++;
912-
}
913-
INode[] inodes = new INode[depth];
914-
915-
// fill up the inodes in the path from this inode to root
916-
for (int i = 0; i < depth; i++) {
917-
if (inode == null) {
918-
NameNode.stateChangeLog.warn("Could not get full path."
919-
+ " Corresponding file might have deleted already.");
920-
return null;
921-
}
922-
inodes[depth-i-1] = inode;
923-
inode = inode.getParent();
924-
}
925-
return inodes;
926-
}
927-
928-
private static INode[] getFullPathINodes(INode inode) {
929-
return getRelativePathINodes(inode, null);
930-
}
931-
932-
/** Return the full path name of the specified inode */
933-
static String getFullPathName(INode inode) {
934-
INode[] inodes = getFullPathINodes(inode);
935-
// inodes can be null only when its called without holding lock
936-
return inodes == null ? "" : getFullPathName(inodes, inodes.length - 1);
937-
}
938-
939888
/**
940889
* Add the given child to the namespace.
941890
* @param existing the INodesInPath containing all the ancestral INodes
@@ -987,9 +936,7 @@ static void verifyQuota(INodesInPath iip, int pos, QuotaCounts deltas,
987936
try {
988937
q.verifyQuota(deltas);
989938
} catch (QuotaExceededException e) {
990-
List<INode> inodes = iip.getReadOnlyINodes();
991-
final String path = getFullPathName(inodes.toArray(new INode[inodes.size()]), i);
992-
e.setPathName(path);
939+
e.setPathName(iip.getPath(i));
993940
throw e;
994941
}
995942
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5085,7 +5085,7 @@ Collection<CorruptFileBlockInfo> listCorruptFileBlocks(String path,
50855085
final INodeFile inode = getBlockCollection(blk);
50865086
skip++;
50875087
if (inode != null && blockManager.countNodes(blk).liveReplicas() == 0) {
5088-
String src = FSDirectory.getFullPathName(inode);
5088+
String src = inode.getFullPathName();
50895089
if (src.startsWith(path)){
50905090
corruptFiles.add(new CorruptFileBlockInfo(src, blk));
50915091
count++;

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INode.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,25 @@ public final byte[] getKey() {
569569

570570
public String getFullPathName() {
571571
// Get the full path name of this inode.
572-
return FSDirectory.getFullPathName(this);
572+
if (isRoot()) {
573+
return Path.SEPARATOR;
574+
}
575+
// compute size of needed bytes for the path
576+
int idx = 0;
577+
for (INode inode = this; inode != null; inode = inode.getParent()) {
578+
// add component + delimiter (if not tail component)
579+
idx += inode.getLocalNameBytes().length + (inode != this ? 1 : 0);
580+
}
581+
byte[] path = new byte[idx];
582+
for (INode inode = this; inode != null; inode = inode.getParent()) {
583+
if (inode != this) {
584+
path[--idx] = Path.SEPARATOR_CHAR;
585+
}
586+
byte[] name = inode.getLocalNameBytes();
587+
idx -= name.length;
588+
System.arraycopy(name, 0, path, idx, name.length);
589+
}
590+
return DFSUtil.bytes2String(path);
573591
}
574592

575593
@Override

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodesInPath.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,11 @@ public String getPath() {
347347
}
348348

349349
public String getParentPath() {
350-
return getPath(path.length - 1);
350+
return getPath(path.length - 2);
351351
}
352352

353353
public String getPath(int pos) {
354-
return DFSUtil.byteArray2PathString(path, 0, pos);
354+
return DFSUtil.byteArray2PathString(path, 0, pos + 1); // it's a length...
355355
}
356356

357357
/**

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSnapshotPathINodes.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,12 @@ public void testNonSnapshotPathINodes() throws Exception {
155155
sub1.toString());
156156
assertEquals(nodesInPath.getINode(components.length - 3).getFullPathName(),
157157
dir.toString());
158-
158+
159+
assertEquals(Path.SEPARATOR, nodesInPath.getPath(0));
160+
assertEquals(dir.toString(), nodesInPath.getPath(1));
161+
assertEquals(sub1.toString(), nodesInPath.getPath(2));
162+
assertEquals(file1.toString(), nodesInPath.getPath(3));
163+
159164
nodesInPath = INodesInPath.resolve(fsdir.rootDir, components, false);
160165
assertEquals(nodesInPath.length(), components.length);
161166
assertSnapshot(nodesInPath, false, null, -1);

0 commit comments

Comments
 (0)