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