Mercurial > hg4j
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 } |