diff options
author | Andrey Loskutov <loskutov@gmx.de> | 2014-07-30 10:42:30 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2014-07-30 23:37:27 +0200 |
commit | 3a161ac467d431313d92b02700ecb6118f3b5925 (patch) | |
tree | 6188a7ac3412905e1571b8e2db05b3b63b7d33c5 /org.eclipse.jgit/src | |
parent | 0307123e5a72f08f75148fd548d689f165886510 (diff) | |
download | jgit-3a161ac467d431313d92b02700ecb6118f3b5925.tar.gz jgit-3a161ac467d431313d92b02700ecb6118f3b5925.zip |
Small performance optimization for ignore rules/fnmatcher
- don't check empty segments generated by String.split()
- don't continue to add segments if the matcher fails to match input
- don't add empty heads
- don't iterate over empty heads.
Bug: 440732
Change-Id: I7d04dccfe24d91275d17ba246662337d6dba66df
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java | 16 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java | 20 |
2 files changed, 28 insertions, 8 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java index 92a4837b2e..f9c239431a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java @@ -307,7 +307,11 @@ public class FileNameMatcher { return new WildCardHead(star); } - private void extendStringToMatchByOneCharacter(final char c) { + /** + * @param c new character to append + * @return true to continue, false if the matcher can stop appending + */ + private boolean extendStringToMatchByOneCharacter(final char c) { final List<Head> newHeads = listForLocalUseage; newHeads.clear(); List<Head> lastAddedHeads = null; @@ -320,12 +324,14 @@ public class FileNameMatcher { // This is the case with the heads "a" and "*" of "a*b" which // both can return the list ["*","b"] if (headsToAdd != lastAddedHeads) { - newHeads.addAll(headsToAdd); + if (!headsToAdd.isEmpty()) + newHeads.addAll(headsToAdd); lastAddedHeads = headsToAdd; } } listForLocalUseage = heads; heads = newHeads; + return !newHeads.isEmpty(); } private static int indexOfUnescaped(final String searchString, @@ -349,7 +355,8 @@ public class FileNameMatcher { public void append(final String stringToMatch) { for (int i = 0; i < stringToMatch.length(); i++) { final char c = stringToMatch.charAt(i); - extendStringToMatchByOneCharacter(c); + if (!extendStringToMatchByOneCharacter(c)) + break; } } @@ -378,6 +385,9 @@ public class FileNameMatcher { * @return true, if the string currently being matched does match. */ public boolean isMatch() { + if (heads.isEmpty()) + return false; + final ListIterator<Head> headIterator = heads .listIterator(heads.size()); while (headIterator.hasPrevious()) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java index fd095d76d6..42bbd9e9b8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java @@ -191,6 +191,9 @@ public class IgnoreRule { final String[] segments = target.split("/"); //$NON-NLS-1$ for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; if (segmentName.equals(pattern) && doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) return true; @@ -207,6 +210,9 @@ public class IgnoreRule { if (nameOnly) { for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; //Iterate through each sub-directory matcher.reset(); matcher.append(segmentName); @@ -218,14 +224,18 @@ public class IgnoreRule { //TODO: This is the slowest operation //This matches e.g. "/src/ne?" to "/src/new/file.c" matcher.reset(); + for (int idx = 0; idx < segments.length; idx++) { final String segmentName = segments[idx]; - if (segmentName.length() > 0) { - matcher.append("/" + segmentName); //$NON-NLS-1$ - } + // String.split("/") creates empty segment for leading slash + if (segmentName.length() == 0) + continue; - if (matcher.isMatch() && - doesMatchDirectoryExpectations(isDirectory, idx, segments.length)) + matcher.append("/" + segmentName); //$NON-NLS-1$ + + if (matcher.isMatch() + && doesMatchDirectoryExpectations(isDirectory, idx, + segments.length)) return true; } } |