Mercurial > hg4j
diff src/org/tmatesoft/hg/repo/HgIgnore.java @ 694:7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 17:42:10 +0200 |
parents | 5c68567b3645 |
children |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgIgnore.java Mon Aug 05 12:45:36 2013 +0200 +++ b/src/org/tmatesoft/hg/repo/HgIgnore.java Mon Aug 05 17:42:10 2013 +0200 @@ -25,7 +25,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -44,11 +46,16 @@ private List<Pattern> entries; private final PathRewrite globPathHelper; - private FileChangeMonitor ignoreFileTracker; + private FileChangeMonitor ignoreFileTracker; + // if pattern matches first fragment of a path, it will + // match any other path with this fragment, so we can avoid pattern matching + // if path starts with one of such fragments (often for e.g. ignored 'bin/' folders) + private final Set<String> ignoredFirstFragments; HgIgnore(PathRewrite globPathRewrite) { entries = Collections.emptyList(); globPathHelper = globPathRewrite; + ignoredFirstFragments = new HashSet<String>(); } /* package-local */ void read(Internals repo) throws HgInvalidControlFileException { @@ -230,18 +237,28 @@ */ public boolean isIgnored(Path path) { String ps = path.toString(); + int x = ps.indexOf('/'); + if (x != -1 && ignoredFirstFragments.contains(ps.substring(0, x))) { + return true; + } for (Pattern p : entries) { - int x = ps.indexOf('/'); // reset for each pattern if (p.matcher(ps).find()) { return true; } - while (x != -1 && x+1 != ps.length() /*skip very last segment not to check complete string twice*/) { - String fragment = ps.substring(0, x); + } + boolean firstFragment = true; + while (x != -1 && x+1 != ps.length() /*skip very last segment not to check complete string twice*/) { + String fragment = ps.substring(0, x); + for (Pattern p : entries) { if (p.matcher(fragment).matches()) { + if (firstFragment) { + ignoredFirstFragments.add(new String(fragment)); + } return true; } - x = ps.indexOf('/', x+1); } + x = ps.indexOf('/', x+1); + firstFragment = false; } return false; }