Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2014-07-30 08:42:30 +0000
committerMatthias Sohn2014-07-30 21:37:27 +0000
commit3a161ac467d431313d92b02700ecb6118f3b5925 (patch)
tree6188a7ac3412905e1571b8e2db05b3b63b7d33c5
parent0307123e5a72f08f75148fd548d689f165886510 (diff)
downloadjgit-3a161ac467d431313d92b02700ecb6118f3b5925.tar.gz
jgit-3a161ac467d431313d92b02700ecb6118f3b5925.tar.xz
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>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreRule.java20
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;
}
}

Back to the top