< prev index next >
src/java.base/unix/classes/java/io/UnixFileSystem.java
Print this page
rev 59556 : 8246338: Reduce overhead of normalizing file paths
Reviewed-by: TBD
@@ -62,18 +62,21 @@
}
/* A normal Unix pathname contains no duplicate slashes and does not end
with a slash. It may be the empty string. */
- /* Normalize the given pathname, whose length is len, starting at the given
- offset; everything before this offset is already normal. */
- private String normalize(String pathname, int len, int off) {
- if (len == 0) return pathname;
- int n = len;
+ /**
+ * Normalize the given pathname, starting at the given
+ * offset; everything before off is already normal, and there's at least
+ * one duplicate or trailing slash to be removed
+ */
+ private String normalize(String pathname, int off) {
+ int n = pathname.length();
while ((n > 0) && (pathname.charAt(n - 1) == '/')) n--;
if (n == 0) return "/";
- StringBuilder sb = new StringBuilder(pathname.length());
+
+ StringBuilder sb = new StringBuilder(n);
if (off > 0) sb.append(pathname, 0, off);
char prevChar = 0;
for (int i = off; i < n; i++) {
char c = pathname.charAt(i);
if ((prevChar == '/') && (c == '/')) continue;
@@ -86,26 +89,23 @@
/* Check that the given pathname is normal. If not, invoke the real
normalizer on the part of the pathname that requires normalization.
This way we iterate through the whole pathname string only once. */
@Override
public String normalize(String pathname) {
- int n = pathname.length();
- char prevChar = 0;
- for (int i = 0; i < n; i++) {
- char c = pathname.charAt(i);
- if ((prevChar == '/') && (c == '/'))
- return normalize(pathname, n, i - 1);
- prevChar = c;
+ int doubleSlash = pathname.indexOf("//");
+ if (doubleSlash >= 0) {
+ return normalize(pathname, doubleSlash);
+ }
+ if (pathname.endsWith("/")) {
+ return normalize(pathname, pathname.length() - 1);
}
- if (prevChar == '/') return normalize(pathname, n, n - 1);
return pathname;
}
@Override
public int prefixLength(String pathname) {
- if (pathname.isEmpty()) return 0;
- return (pathname.charAt(0) == '/') ? 1 : 0;
+ return pathname.startsWith("/") ? 1 : 0;
}
@Override
public String resolve(String parent, String child) {
if (child.isEmpty()) return parent;
< prev index next >