HDFS-10656. Optimize conversion of byte arrays back to path string. Contributed by Daryn Sharp.

This commit is contained in:
Kihwal Lee 2016-08-03 11:53:41 -05:00
parent 2d8227605f
commit bebf10d245
1 changed files with 30 additions and 18 deletions

View File

@ -84,7 +84,6 @@ import org.apache.hadoop.security.authorize.AccessControlList;
import org.apache.hadoop.util.ToolRunner; import org.apache.hadoop.util.ToolRunner;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -267,27 +266,40 @@ public class DFSUtil {
/** /**
* Given a list of path components returns a path as a UTF8 String * Given a list of path components returns a path as a UTF8 String
*/ */
public static String byteArray2PathString(byte[][] pathComponents, public static String byteArray2PathString(final byte[][] components,
int offset, int length) { final int offset, final int length) {
if (pathComponents.length == 0) { // specifically not using StringBuilder to more efficiently build
// string w/o excessive byte[] copies and charset conversions.
final int range = offset + length;
Preconditions.checkPositionIndexes(offset, range, components.length);
if (length == 0) {
return ""; return "";
} }
Preconditions.checkArgument(offset >= 0 && offset < pathComponents.length); // absolute paths start with either null or empty byte[]
Preconditions.checkArgument(length >= 0 && offset + length <= byte[] firstComponent = components[offset];
pathComponents.length); boolean isAbsolute = (offset == 0 &&
if (offset == 0 && length == 1 (firstComponent == null || firstComponent.length == 0));
&& (pathComponents[0] == null || pathComponents[0].length == 0)) { if (offset == 0 && length == 1) {
return Path.SEPARATOR; return isAbsolute ? Path.SEPARATOR : bytes2String(firstComponent);
} }
StringBuilder result = new StringBuilder(); // compute length of full byte[], seed with 1st component and delimiters
int lastIndex = offset + length - 1; int pos = isAbsolute ? 0 : firstComponent.length;
for (int i = offset; i <= lastIndex; i++) { int size = pos + length - 1;
result.append(new String(pathComponents[i], Charsets.UTF_8)); for (int i=offset + 1; i < range; i++) {
if (i < lastIndex) { size += components[i].length;
result.append(Path.SEPARATOR_CHAR);
} }
final byte[] result = new byte[size];
if (!isAbsolute) {
System.arraycopy(firstComponent, 0, result, 0, firstComponent.length);
} }
return result.toString(); // append remaining components as "/component".
for (int i=offset + 1; i < range; i++) {
result[pos++] = (byte)Path.SEPARATOR_CHAR;
int len = components[i].length;
System.arraycopy(components[i], 0, result, pos, len);
pos += len;
}
return bytes2String(result);
} }
public static String byteArray2PathString(byte[][] pathComponents) { public static String byteArray2PathString(byte[][] pathComponents) {