Mercurial > jhg
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 /** |
