The checkPath function is available as a byte[] form, in fact the String form just converts to byte[] to run the algorithm. Having DirCacheEntry take a byte[] -> String -> byte[] to check if each path is valid is a huge waste of CPU time. On some systems it can double the time required to read 38,999 files from trees to the DirCache. This slows down any operation using a DirCache. Expose the byte[] form and use it for DirCacheEntry creation. Change-Id: I6db7bc793ece99ff3c356338d793c07c061aeac7tags/v4.2.0.201601211800-r
@@ -69,9 +69,9 @@ public class DirCacheEntryTest { | |||
assertFalse(isValidPath("a\u0000b")); | |||
} | |||
private static boolean isValidPath(final String path) { | |||
private static boolean isValidPath(String path) { | |||
try { | |||
DirCacheCheckout.checkValidPath(path); | |||
new DirCacheEntry(path); | |||
return true; | |||
} catch (InvalidPathException e) { | |||
return false; |
@@ -1342,24 +1342,6 @@ public class DirCacheCheckout { | |||
checkValidPathSegment(chk, i); | |||
} | |||
/** | |||
* Check if path is a valid path for a checked out file name or ref name. | |||
* | |||
* @param path | |||
* @throws InvalidPathException | |||
* if the path is invalid | |||
* @since 3.3 | |||
*/ | |||
static void checkValidPath(String path) throws InvalidPathException { | |||
try { | |||
SystemReader.getInstance().checkPath(path); | |||
} catch (CorruptObjectException e) { | |||
InvalidPathException p = new InvalidPathException(path); | |||
p.initCause(e); | |||
throw p; | |||
} | |||
} | |||
private static void checkValidPathSegment(ObjectChecker chk, | |||
CanonicalTreeParser t) throws InvalidPathException { | |||
try { |
@@ -65,6 +65,7 @@ import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.util.IO; | |||
import org.eclipse.jgit.util.MutableInteger; | |||
import org.eclipse.jgit.util.NB; | |||
import org.eclipse.jgit.util.SystemReader; | |||
/** | |||
* A single file (or stage of a file) in a {@link DirCache}. | |||
@@ -191,7 +192,7 @@ public class DirCacheEntry { | |||
} | |||
try { | |||
DirCacheCheckout.checkValidPath(toString(path)); | |||
checkPath(path); | |||
} catch (InvalidPathException e) { | |||
CorruptObjectException p = | |||
new CorruptObjectException(e.getMessage()); | |||
@@ -263,7 +264,7 @@ public class DirCacheEntry { | |||
/** | |||
* Create an empty entry at the specified stage. | |||
* | |||
* @param newPath | |||
* @param path | |||
* name of the cache entry, in the standard encoding. | |||
* @param stage | |||
* the stage index of the new entry. | |||
@@ -274,16 +275,16 @@ public class DirCacheEntry { | |||
* range 0..3, inclusive. | |||
*/ | |||
@SuppressWarnings("boxing") | |||
public DirCacheEntry(final byte[] newPath, final int stage) { | |||
DirCacheCheckout.checkValidPath(toString(newPath)); | |||
public DirCacheEntry(byte[] path, final int stage) { | |||
checkPath(path); | |||
if (stage < 0 || 3 < stage) | |||
throw new IllegalArgumentException(MessageFormat.format( | |||
JGitText.get().invalidStageForPath, | |||
stage, toString(newPath))); | |||
stage, toString(path))); | |||
info = new byte[INFO_LEN]; | |||
infoOffset = 0; | |||
path = newPath; | |||
this.path = path; | |||
int flags = ((stage & 0x3) << 12); | |||
if (path.length < NAME_MASK) | |||
@@ -730,6 +731,16 @@ public class DirCacheEntry { | |||
return 0; | |||
} | |||
private static void checkPath(byte[] path) { | |||
try { | |||
SystemReader.getInstance().checkPath(path); | |||
} catch (CorruptObjectException e) { | |||
InvalidPathException p = new InvalidPathException(toString(path)); | |||
p.initCause(e); | |||
throw p; | |||
} | |||
} | |||
private static String toString(final byte[] path) { | |||
return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString(); | |||
} |
@@ -339,4 +339,19 @@ public abstract class SystemReader { | |||
public void checkPath(String path) throws CorruptObjectException { | |||
platformChecker.checkPath(path); | |||
} | |||
/** | |||
* Check tree path entry for validity. | |||
* <p> | |||
* Scans a multi-directory path string such as {@code "src/main.c"}. | |||
* | |||
* @param path | |||
* path string to scan. | |||
* @throws CorruptObjectException | |||
* path is invalid. | |||
* @since 4.2 | |||
*/ | |||
public void checkPath(byte[] path) throws CorruptObjectException { | |||
platformChecker.checkPath(path, 0, path.length); | |||
} | |||
} |