Mercurial > hg4j
comparison 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 |
comparison
equal
deleted
inserted
replaced
693:32b0d19e8aba | 694:7efabe0cddcf |
---|---|
23 import java.io.File; | 23 import java.io.File; |
24 import java.io.FileReader; | 24 import java.io.FileReader; |
25 import java.io.IOException; | 25 import java.io.IOException; |
26 import java.util.ArrayList; | 26 import java.util.ArrayList; |
27 import java.util.Collections; | 27 import java.util.Collections; |
28 import java.util.HashSet; | |
28 import java.util.List; | 29 import java.util.List; |
30 import java.util.Set; | |
29 import java.util.regex.Pattern; | 31 import java.util.regex.Pattern; |
30 import java.util.regex.PatternSyntaxException; | 32 import java.util.regex.PatternSyntaxException; |
31 | 33 |
32 import org.tmatesoft.hg.internal.FileChangeMonitor; | 34 import org.tmatesoft.hg.internal.FileChangeMonitor; |
33 import org.tmatesoft.hg.internal.Internals; | 35 import org.tmatesoft.hg.internal.Internals; |
42 */ | 44 */ |
43 public class HgIgnore implements Path.Matcher { | 45 public class HgIgnore implements Path.Matcher { |
44 | 46 |
45 private List<Pattern> entries; | 47 private List<Pattern> entries; |
46 private final PathRewrite globPathHelper; | 48 private final PathRewrite globPathHelper; |
47 private FileChangeMonitor ignoreFileTracker; | 49 private FileChangeMonitor ignoreFileTracker; |
50 // if pattern matches first fragment of a path, it will | |
51 // match any other path with this fragment, so we can avoid pattern matching | |
52 // if path starts with one of such fragments (often for e.g. ignored 'bin/' folders) | |
53 private final Set<String> ignoredFirstFragments; | |
48 | 54 |
49 HgIgnore(PathRewrite globPathRewrite) { | 55 HgIgnore(PathRewrite globPathRewrite) { |
50 entries = Collections.emptyList(); | 56 entries = Collections.emptyList(); |
51 globPathHelper = globPathRewrite; | 57 globPathHelper = globPathRewrite; |
58 ignoredFirstFragments = new HashSet<String>(); | |
52 } | 59 } |
53 | 60 |
54 /* package-local */ void read(Internals repo) throws HgInvalidControlFileException { | 61 /* package-local */ void read(Internals repo) throws HgInvalidControlFileException { |
55 File ignoreFile = repo.getRepositoryFile(HgIgnore); | 62 File ignoreFile = repo.getRepositoryFile(HgIgnore); |
56 BufferedReader fr = null; | 63 BufferedReader fr = null; |
228 * @param path file or directory name in question | 235 * @param path file or directory name in question |
229 * @return <code>true</code> if matches repository configuration of ignored files. | 236 * @return <code>true</code> if matches repository configuration of ignored files. |
230 */ | 237 */ |
231 public boolean isIgnored(Path path) { | 238 public boolean isIgnored(Path path) { |
232 String ps = path.toString(); | 239 String ps = path.toString(); |
240 int x = ps.indexOf('/'); | |
241 if (x != -1 && ignoredFirstFragments.contains(ps.substring(0, x))) { | |
242 return true; | |
243 } | |
233 for (Pattern p : entries) { | 244 for (Pattern p : entries) { |
234 int x = ps.indexOf('/'); // reset for each pattern | |
235 if (p.matcher(ps).find()) { | 245 if (p.matcher(ps).find()) { |
236 return true; | 246 return true; |
237 } | 247 } |
238 while (x != -1 && x+1 != ps.length() /*skip very last segment not to check complete string twice*/) { | 248 } |
239 String fragment = ps.substring(0, x); | 249 boolean firstFragment = true; |
250 while (x != -1 && x+1 != ps.length() /*skip very last segment not to check complete string twice*/) { | |
251 String fragment = ps.substring(0, x); | |
252 for (Pattern p : entries) { | |
240 if (p.matcher(fragment).matches()) { | 253 if (p.matcher(fragment).matches()) { |
254 if (firstFragment) { | |
255 ignoredFirstFragments.add(new String(fragment)); | |
256 } | |
241 return true; | 257 return true; |
242 } | 258 } |
243 x = ps.indexOf('/', x+1); | 259 } |
244 } | 260 x = ps.indexOf('/', x+1); |
261 firstFragment = false; | |
245 } | 262 } |
246 return false; | 263 return false; |
247 } | 264 } |
248 | 265 |
249 /** | 266 /** |