comparison src/org/tmatesoft/hg/repo/HgStatusCollector.java @ 285:6dbbc53fc46d

Use Path instead of plain String for manifest file names
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sat, 03 Sep 2011 21:46:13 +0200
parents 7232b94f2ae3
children a7a3395a519e
comparison
equal deleted inserted replaced
284:7232b94f2ae3 285:6dbbc53fc46d
25 import java.util.LinkedList; 25 import java.util.LinkedList;
26 import java.util.List; 26 import java.util.List;
27 import java.util.Map; 27 import java.util.Map;
28 import java.util.TreeSet; 28 import java.util.TreeSet;
29 29
30 import org.tmatesoft.hg.core.HgBadStateException;
30 import org.tmatesoft.hg.core.HgDataStreamException; 31 import org.tmatesoft.hg.core.HgDataStreamException;
31 import org.tmatesoft.hg.core.Nodeid; 32 import org.tmatesoft.hg.core.Nodeid;
32 import org.tmatesoft.hg.internal.IntMap; 33 import org.tmatesoft.hg.internal.IntMap;
33 import org.tmatesoft.hg.internal.ManifestRevision; 34 import org.tmatesoft.hg.internal.ManifestRevision;
34 import org.tmatesoft.hg.internal.Pool; 35 import org.tmatesoft.hg.internal.Pool;
52 // no cache limit, but with cached nodeids and filenames - 1730+ 53 // no cache limit, but with cached nodeids and filenames - 1730+
53 // cache limit 100 - 19+ minutes to process 10000, and still working (too long, stopped) 54 // cache limit 100 - 19+ minutes to process 10000, and still working (too long, stopped)
54 private final int cacheMaxSize = 50; // do not keep too much manifest revisions 55 private final int cacheMaxSize = 50; // do not keep too much manifest revisions
55 private PathPool pathPool; 56 private PathPool pathPool;
56 private final Pool<Nodeid> cacheNodes; 57 private final Pool<Nodeid> cacheNodes;
57 private final Pool<String> cacheFilenames; // XXX in fact, need to think if use of PathPool directly instead is better solution 58 private final Pool<Path> cacheFilenames;
58 private final ManifestRevision emptyFakeState; 59 private final ManifestRevision emptyFakeState;
59 private Path.Matcher scope = new Path.Matcher.Any(); 60 private Path.Matcher scope = new Path.Matcher.Any();
60 61
61 62
62 public HgStatusCollector(HgRepository hgRepo) { 63 public HgStatusCollector(HgRepository hgRepo) {
63 this.repo = hgRepo; 64 this.repo = hgRepo;
64 cache = new IntMap<ManifestRevision>(cacheMaxSize); 65 cache = new IntMap<ManifestRevision>(cacheMaxSize);
65 cacheNodes = new Pool<Nodeid>(); 66 cacheNodes = new Pool<Nodeid>();
66 cacheFilenames = new Pool<String>(); 67 cacheFilenames = new Pool<Path>();
67 68
68 emptyFakeState = createEmptyManifestRevision(); 69 emptyFakeState = createEmptyManifestRevision();
69 } 70 }
70 71
71 public HgRepository getRepo() { 72 public HgRepository getRepo() {
97 } 98 }
98 } 99 }
99 100
100 private void initCacheRange(int minRev, int maxRev) { 101 private void initCacheRange(int minRev, int maxRev) {
101 ensureCacheSize(); 102 ensureCacheSize();
102 repo.getManifest().walk(minRev, maxRev, new HgManifest.Inspector() { 103 repo.getManifest().walk(minRev, maxRev, new HgManifest.Inspector2() {
103 private ManifestRevision delegate; 104 private ManifestRevision delegate;
104 private boolean cacheHit; // range may include revisions we already know about, do not re-create them 105 private boolean cacheHit; // range may include revisions we already know about, do not re-create them
105 106
106 public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) { 107 public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) {
107 assert delegate == null; 108 assert delegate == null;
116 } 117 }
117 return true; 118 return true;
118 } 119 }
119 120
120 public boolean next(Nodeid nid, String fname, String flags) { 121 public boolean next(Nodeid nid, String fname, String flags) {
122 throw new HgBadStateException(HgManifest.Inspector2.class.getName());
123 }
124
125 public boolean next(Nodeid nid, Path fname, HgManifest.Flags flags) {
121 if (!cacheHit) { 126 if (!cacheHit) {
122 delegate.next(nid, fname, flags); 127 delegate.next(nid, fname, flags);
123 } 128 }
124 return true; 129 return true;
125 } 130 }
227 } 232 }
228 } 233 }
229 r1 = get(rev1); 234 r1 = get(rev1);
230 r2 = get(rev2); 235 r2 = get(rev2);
231 236
232 PathPool pp = getPathPool(); 237 TreeSet<Path> r1Files = new TreeSet<Path>(r1.files());
233 TreeSet<String> r1Files = new TreeSet<String>(r1.files()); 238 for (Path r2fname : r2.files()) {
234 for (String fname : r2.files()) { 239 if (!scope.accept(r2fname)) {
235 final Path r2filePath = pp.path(fname);
236 if (!scope.accept(r2filePath)) {
237 continue; 240 continue;
238 } 241 }
239 if (r1Files.remove(fname)) { 242 if (r1Files.remove(r2fname)) {
240 Nodeid nidR1 = r1.nodeid(fname); 243 Nodeid nidR1 = r1.nodeid(r2fname);
241 Nodeid nidR2 = r2.nodeid(fname); 244 Nodeid nidR2 = r2.nodeid(r2fname);
242 String flagsR1 = r1.flags(fname); 245 HgManifest.Flags flagsR1 = r1.flags(r2fname);
243 String flagsR2 = r2.flags(fname); 246 HgManifest.Flags flagsR2 = r2.flags(r2fname);
244 if (nidR1.equals(nidR2) && ((flagsR2 == null && flagsR1 == null) || (flagsR2 != null && flagsR2.equals(flagsR1)))) { 247 if (nidR1.equals(nidR2) && flagsR2 == flagsR1) {
245 inspector.clean(r2filePath); 248 inspector.clean(r2fname);
246 } else { 249 } else {
247 inspector.modified(r2filePath); 250 inspector.modified(r2fname);
248 } 251 }
249 } else { 252 } else {
250 try { 253 try {
251 Path copyTarget = r2filePath; 254 Path copyTarget = r2fname;
252 Path copyOrigin = getOriginIfCopy(repo, copyTarget, r1Files, rev1); 255 Path copyOrigin = getOriginIfCopy(repo, copyTarget, r1Files, rev1);
253 if (copyOrigin != null) { 256 if (copyOrigin != null) {
254 inspector.copied(pp.path(copyOrigin) /*pipe through pool, just in case*/, copyTarget); 257 inspector.copied(getPathPool().path(copyOrigin) /*pipe through pool, just in case*/, copyTarget);
255 } else { 258 } else {
256 inspector.added(copyTarget); 259 inspector.added(copyTarget);
257 } 260 }
258 } catch (HgDataStreamException ex) { 261 } catch (HgDataStreamException ex) {
259 ex.printStackTrace(); 262 ex.printStackTrace();
260 // FIXME perhaps, shall record this exception to dedicated mediator and continue 263 // FIXME perhaps, shall record this exception to dedicated mediator and continue
261 // for a single file not to be irresolvable obstacle for a status operation 264 // for a single file not to be irresolvable obstacle for a status operation
262 } 265 }
263 } 266 }
264 } 267 }
265 for (String left : r1Files) { 268 for (Path r1fname : r1Files) {
266 final Path r2filePath = pp.path(left); 269 if (scope.accept(r1fname)) {
267 if (scope.accept(r2filePath)) { 270 inspector.removed(r1fname);
268 inspector.removed(r2filePath);
269 } 271 }
270 } 272 }
271 } 273 }
272 274
273 public Record status(int rev1, int rev2) { 275 public Record status(int rev1, int rev2) {
274 Record rv = new Record(); 276 Record rv = new Record();
275 walk(rev1, rev2, rv); 277 walk(rev1, rev2, rv);
276 return rv; 278 return rv;
277 } 279 }
278 280
279 /*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Collection<String> originals, int originalChangelogRevision) throws HgDataStreamException { 281 /*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Collection<Path> originals, int originalChangelogRevision) throws HgDataStreamException {
280 HgDataFile df = hgRepo.getFileNode(fname); 282 HgDataFile df = hgRepo.getFileNode(fname);
281 while (df.isCopy()) { 283 while (df.isCopy()) {
282 Path original = df.getCopySourceName(); 284 Path original = df.getCopySourceName();
283 if (originals.contains(original.toString())) { 285 if (originals.contains(original)) {
284 df = hgRepo.getFileNode(original); 286 df = hgRepo.getFileNode(original);
285 int changelogRevision = df.getChangesetLocalRevision(0); 287 int changelogRevision = df.getChangesetLocalRevision(0);
286 if (changelogRevision <= originalChangelogRevision) { 288 if (changelogRevision <= originalChangelogRevision) {
287 // copy/rename source was known prior to rev1 289 // copy/rename source was known prior to rev1
288 // (both r1Files.contains is true and original was created earlier than rev1) 290 // (both r1Files.contains is true and original was created earlier than rev1)
324 return null; 326 return null;
325 } 327 }
326 if ((modified == null || !modified.contains(fname)) && (removed == null || !removed.contains(fname))) { 328 if ((modified == null || !modified.contains(fname)) && (removed == null || !removed.contains(fname))) {
327 return null; 329 return null;
328 } 330 }
329 return statusHelper.raw(startRev).nodeid(fname.toString()); 331 return statusHelper.raw(startRev).nodeid(fname);
330 } 332 }
331 public Nodeid nodeidAfterChange(Path fname) { 333 public Nodeid nodeidAfterChange(Path fname) {
332 if (statusHelper == null || endRev == BAD_REVISION) { 334 if (statusHelper == null || endRev == BAD_REVISION) {
333 return null; 335 return null;
334 } 336 }
335 if ((modified == null || !modified.contains(fname)) && (added == null || !added.contains(fname))) { 337 if ((modified == null || !modified.contains(fname)) && (added == null || !added.contains(fname))) {
336 return null; 338 return null;
337 } 339 }
338 return statusHelper.raw(endRev).nodeid(fname.toString()); 340 return statusHelper.raw(endRev).nodeid(fname);
339 } 341 }
340 342
341 public List<Path> getModified() { 343 public List<Path> getModified() {
342 return proper(modified); 344 return proper(modified);
343 } 345 }