Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/MapTagsToFileRevisions.java @ 438:0d128e09d70f
Yet another alternative to collect tags for a file
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 19 Apr 2012 19:16:45 +0200 |
parents | 9265f7f4b49b |
children | 6526d8adbc0f |
comparison
equal
deleted
inserted
replaced
437:32184ddcf46d | 438:0d128e09d70f |
---|---|
3 import static org.tmatesoft.hg.repo.HgRepository.TIP; | 3 import static org.tmatesoft.hg.repo.HgRepository.TIP; |
4 | 4 |
5 import java.io.File; | 5 import java.io.File; |
6 import java.util.ArrayList; | 6 import java.util.ArrayList; |
7 import java.util.Arrays; | 7 import java.util.Arrays; |
8 import java.util.Collections; | |
8 import java.util.HashMap; | 9 import java.util.HashMap; |
9 import java.util.LinkedList; | 10 import java.util.LinkedList; |
10 import java.util.List; | 11 import java.util.List; |
11 import java.util.Map; | 12 import java.util.Map; |
12 | 13 |
53 } | 54 } |
54 | 55 |
55 | 56 |
56 // revision == 2406 - 5 ms per run (baseRevision == 2406) | 57 // revision == 2406 - 5 ms per run (baseRevision == 2406) |
57 // revision == 2405 - 69 ms per run (baseRevision == 1403) | 58 // revision == 2405 - 69 ms per run (baseRevision == 1403) |
58 private void measurePatchAffectsArbitraryRevisionRead() throws Exception { | 59 public void measurePatchAffectsArbitraryRevisionRead() throws Exception { |
59 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | 60 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); |
60 final DoNothingManifestInspector insp = new DoNothingManifestInspector(); | 61 final DoNothingManifestInspector insp = new DoNothingManifestInspector(); |
61 final int revision = 2405; | 62 final int revision = 2405; |
62 // warm-up. | 63 // warm-up. |
63 repository.getManifest().walk(revision, revision, insp); | 64 repository.getManifest().walk(revision, revision, insp); |
179 * RevisionMap.revisionIndex: ~265 ms (almost 100% in #init()) | 180 * RevisionMap.revisionIndex: ~265 ms (almost 100% in #init()) |
180 * each 1000'th revision, total 71 revision: 1 230 vs 270 | 181 * each 1000'th revision, total 71 revision: 1 230 vs 270 |
181 * each 2000'th revision, total 36 revision: 620 vs 270 | 182 * each 2000'th revision, total 36 revision: 620 vs 270 |
182 * each 3000'th revision, total 24 revision: 410 vs 275 | 183 * each 3000'th revision, total 24 revision: 410 vs 275 |
183 */ | 184 */ |
184 private void revisionMap() throws Exception { | 185 public void revisionMap() throws Exception { |
185 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | 186 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); |
186 final HgChangelog clog = repository.getChangelog(); | 187 final HgChangelog clog = repository.getChangelog(); |
187 ArrayList<Nodeid> revisions = new ArrayList<Nodeid>(); | 188 ArrayList<Nodeid> revisions = new ArrayList<Nodeid>(); |
188 final int step = 5000; | 189 final int step = 5000; |
189 for (int i = 0, top = clog.getLastRevision(); i < top; i += step) { | 190 for (int i = 0, top = clog.getLastRevision(); i < top; i += step) { |
208 } | 209 } |
209 } | 210 } |
210 System.out.printf("RevisionMap time: %d ms, of that init() %,d ns\n", (System.nanoTime() - s2) / 1000000, s3 - s2); | 211 System.out.printf("RevisionMap time: %d ms, of that init() %,d ns\n", (System.nanoTime() - s2) / 1000000, s3 - s2); |
211 } | 212 } |
212 | 213 |
213 private void changelogWalk() throws Exception { | 214 public void changelogWalk() throws Exception { |
214 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | 215 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); |
215 final long start = System.currentTimeMillis(); | 216 final long start = System.currentTimeMillis(); |
216 repository.getChangelog().all(new HgChangelog.Inspector() { | 217 repository.getChangelog().all(new HgChangelog.Inspector() { |
217 public int xx = 0; | 218 public int xx = 0; |
218 | 219 |
228 // cpyhton: 13 seconds. Of that, cumulative Patch.apply takes 8.8 seconds, RevlogStream.Inspector.next - 1.8 | 229 // cpyhton: 13 seconds. Of that, cumulative Patch.apply takes 8.8 seconds, RevlogStream.Inspector.next - 1.8 |
229 System.out.printf("Total time: %d ms\n", System.currentTimeMillis() - start); | 230 System.out.printf("Total time: %d ms\n", System.currentTimeMillis() - start); |
230 System.out.printf("Free mem: %,d\n", Runtime.getRuntime().freeMemory()); | 231 System.out.printf("Free mem: %,d\n", Runtime.getRuntime().freeMemory()); |
231 } | 232 } |
232 | 233 |
233 private void manifestWalk() throws Exception { | 234 public void manifestWalk() throws Exception { |
234 System.out.println(System.getProperty("java.version")); | 235 System.out.println(System.getProperty("java.version")); |
235 final long start = System.currentTimeMillis(); | 236 final long start = System.currentTimeMillis(); |
236 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | 237 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); |
237 repository.getManifest().walk(0, 10000, new DoNothingManifestInspector()); | 238 repository.getManifest().walk(0, 10000, new DoNothingManifestInspector()); |
238 // cpython: 1,1 sec for 0..1000, 43 sec for 0..10000, 115 sec for 0..20000 (Pool with HashMap) | 239 // cpython: 1,1 sec for 0..1000, 43 sec for 0..10000, 115 sec for 0..20000 (Pool with HashMap) |
270 tagLocalRevs = copy; | 271 tagLocalRevs = copy; |
271 } | 272 } |
272 return tagLocalRevs; | 273 return tagLocalRevs; |
273 } | 274 } |
274 | 275 |
275 private void collectTagsPerFile() throws HgException, CancelledException { | 276 public void collectTagsPerFile() throws HgException, CancelledException { |
276 final long start = System.currentTimeMillis(); | 277 final long start = System.currentTimeMillis(); |
277 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | 278 final HgRepository repository = new HgLookup().detect(new File("/home/artem/hg/cpython")); |
278 final HgTags tags = repository.getTags(); | 279 final HgTags tags = repository.getTags(); |
279 // | 280 // |
280 // build cache | 281 // build cache |
281 // | 282 // |
282 final TagInfo[] allTags = new TagInfo[tags.getAllTags().size()]; | 283 final TagInfo[] allTags = new TagInfo[tags.getAllTags().size()]; |
293 // | 294 // |
294 collectTagsPerFile_Approach_1(clogrmap, tagLocalRevs, allTags, targetPath); | 295 collectTagsPerFile_Approach_1(clogrmap, tagLocalRevs, allTags, targetPath); |
295 System.out.printf("Total time: %d ms\n", System.currentTimeMillis() - start); | 296 System.out.printf("Total time: %d ms\n", System.currentTimeMillis() - start); |
296 | 297 |
297 System.out.println("\nApproach 2"); | 298 System.out.println("\nApproach 2"); |
298 collectTagsPerFile_Approach_2(repository, tagLocalRevs, tagLocalRev2TagInfo, allTags, targetPath); | 299 collectTagsPerFile_Approach_2(repository, tagLocalRevs, tagLocalRev2TagInfo, targetPath); |
299 } | 300 } |
300 | 301 |
301 // Approach 1. Build map with all files, their revisions and corresponding tags | 302 // Approach 1. Build map with all files, their revisions and corresponding tags |
302 // | 303 // |
303 private void collectTagsPerFile_Approach_1(final HgRevisionMap clogrmap, final int[] tagLocalRevs, final TagInfo[] allTags, Path targetPath) throws HgException { | 304 private void collectTagsPerFile_Approach_1(final HgRevisionMap<HgChangelog> clogrmap, final int[] tagLocalRevs, final TagInfo[] allTags, Path targetPath) throws HgException { |
304 HgRepository repository = clogrmap.getRepo(); | 305 HgRepository repository = clogrmap.getRepo(); |
305 final long start = System.currentTimeMillis(); | 306 final long start = System.currentTimeMillis(); |
306 // file2rev2tag value is array of revisions, always of allTags.length. Revision index in the array | 307 // file2rev2tag value is array of revisions, always of allTags.length. Revision index in the array |
307 // is index of corresponding TagInfo in allTags; | 308 // is index of corresponding TagInfo in allTags; |
308 final Map<Path, Nodeid[]> file2rev2tag = new HashMap<Path, Nodeid[]>(); | 309 final Map<Path, Nodeid[]> file2rev2tag = new HashMap<Path, Nodeid[]>(); |
370 } | 371 } |
371 System.out.printf("%3d%7d%s\n", fileRevIndex, changesetRevIndex, associatedTags); | 372 System.out.printf("%3d%7d%s\n", fileRevIndex, changesetRevIndex, associatedTags); |
372 } | 373 } |
373 } | 374 } |
374 | 375 |
375 private void collectTagsPerFile_Approach_2(HgRepository repository, final int[] tagLocalRevs, final IntMap<List<TagInfo>> tagLocalRev2TagInfo, TagInfo[] allTags, Path targetPath) throws HgException { | 376 private void collectTagsPerFile_Approach_2(HgRepository repository, final int[] tagLocalRevs, final IntMap<List<TagInfo>> tagRevIndex2TagInfo, Path targetPath) throws HgException { |
376 // | 377 // |
377 // Approach 2. No all-file map. Collect file revisions recorded at the time of tagging, | 378 // Approach 2. No all-file map. Collect file revisions recorded at the time of tagging, |
378 // then for each file revision check if it is among those above, and if yes, take corresponding tags | 379 // then for each file revision check if it is among those above, and if yes, take corresponding tags |
379 HgDataFile fileNode = repository.getFileNode(targetPath); | 380 HgDataFile fileNode = repository.getFileNode(targetPath); |
380 final long start2 = System.nanoTime(); | 381 final long start2 = System.nanoTime(); |
381 final int lastRev = fileNode.getLastRevision(); | |
382 final Map<Integer, Nodeid> fileRevisionAtTagRevision = new HashMap<Integer, Nodeid>(); | 382 final Map<Integer, Nodeid> fileRevisionAtTagRevision = new HashMap<Integer, Nodeid>(); |
383 final Map<Nodeid, List<String>> fileRev2TagNames = new HashMap<Nodeid, List<String>>(); | |
383 HgManifest.Inspector collectFileRevAtCset = new HgManifest.Inspector() { | 384 HgManifest.Inspector collectFileRevAtCset = new HgManifest.Inspector() { |
384 | 385 |
385 private int csetRevIndex; | 386 private int csetRevIndex; |
386 | 387 |
387 public boolean next(Nodeid nid, Path fname, Flags flags) { | 388 public boolean next(Nodeid nid, Path fname, Flags flags) { |
388 fileRevisionAtTagRevision.put(csetRevIndex, nid); | 389 fileRevisionAtTagRevision.put(csetRevIndex, nid); |
390 if (tagRevIndex2TagInfo.containsKey(csetRevIndex)) { | |
391 List<String> tags = fileRev2TagNames.get(nid); | |
392 if (tags == null) { | |
393 fileRev2TagNames.put(nid, tags = new ArrayList<String>(3)); | |
394 } | |
395 for (TagInfo ti : tagRevIndex2TagInfo.get(csetRevIndex)) { | |
396 tags.add(ti.name()); | |
397 } | |
398 } | |
389 return true; | 399 return true; |
390 } | 400 } |
391 | 401 |
392 public boolean end(int manifestRevision) { | 402 public boolean end(int manifestRevision) { |
393 return true; | 403 return true; |
397 csetRevIndex = changelogRevision; | 407 csetRevIndex = changelogRevision; |
398 return true; | 408 return true; |
399 } | 409 } |
400 }; | 410 }; |
401 repository.getManifest().walkFileRevisions(targetPath, collectFileRevAtCset,tagLocalRevs); | 411 repository.getManifest().walkFileRevisions(targetPath, collectFileRevAtCset,tagLocalRevs); |
402 | 412 |
403 final long start2a = System.nanoTime(); | 413 final long start2a = System.nanoTime(); |
404 fileNode.indexWalk(0, lastRev, new HgDataFile.RevisionInspector() { | 414 fileNode.indexWalk(0, TIP, new HgDataFile.RevisionInspector() { |
405 | 415 |
406 public void next(int fileRevisionIndex, Nodeid fileRevision, int changesetRevisionIndex) { | 416 public void next(int fileRevisionIndex, Nodeid fileRevision, int changesetRevisionIndex) { |
407 List<String> associatedTags = new LinkedList<String>(); | 417 List<String> associatedTags = new LinkedList<String>(); |
408 for (int taggetRevision : tagLocalRevs) { | 418 |
419 for (int taggedRevision : tagLocalRevs) { | |
409 // current file revision can't appear in tags that point to earlier changelog revisions (they got own file revision) | 420 // current file revision can't appear in tags that point to earlier changelog revisions (they got own file revision) |
410 if (taggetRevision >= changesetRevisionIndex) { | 421 if (taggedRevision >= changesetRevisionIndex) { |
411 // z points to some changeset with tag | 422 // z points to some changeset with tag |
412 Nodeid wasKnownAs = fileRevisionAtTagRevision.get(taggetRevision); | 423 Nodeid wasKnownAs = fileRevisionAtTagRevision.get(taggedRevision); |
413 if (wasKnownAs.equals(fileRevision)) { | 424 if (wasKnownAs.equals(fileRevision)) { |
414 // has tag associated with changeset at index z | 425 // has tag associated with changeset at index z |
415 List<TagInfo> tagsAtRev = tagLocalRev2TagInfo.get(taggetRevision); | 426 List<TagInfo> tagsAtRev = tagRevIndex2TagInfo.get(taggedRevision); |
416 assert tagsAtRev != null; | 427 assert tagsAtRev != null; |
417 for (TagInfo ti : tagsAtRev) { | 428 for (TagInfo ti : tagsAtRev) { |
418 associatedTags.add(ti.name()); | 429 associatedTags.add(ti.name()); |
419 } | 430 } |
420 } | 431 } |
421 } | 432 } |
422 } | 433 } |
434 // | |
423 System.out.printf("%3d%7d%s\n", fileRevisionIndex, changesetRevisionIndex, associatedTags); | 435 System.out.printf("%3d%7d%s\n", fileRevisionIndex, changesetRevisionIndex, associatedTags); |
424 } | 436 } |
425 }); | 437 }); |
438 for (int i = 0, lastRev = fileNode.getLastRevision(); i <= lastRev; i++) { | |
439 Nodeid fileRevision = fileNode.getRevision(i); | |
440 List<String> associatedTags2 = fileRev2TagNames.get(fileRevision); | |
441 int changesetRevIndex = fileNode.getChangesetRevisionIndex(i); | |
442 System.out.printf("%3d%7d%s\n", i, changesetRevIndex, associatedTags2 == null ? Collections.emptyList() : associatedTags2); | |
443 } | |
426 System.out.printf("Alternative total time: %d ms, of that init: %d ms\n", (System.nanoTime() - start2)/1000000, (start2a-start2)/1000000); | 444 System.out.printf("Alternative total time: %d ms, of that init: %d ms\n", (System.nanoTime() - start2)/1000000, (start2a-start2)/1000000); |
427 System.out.printf("Free mem: %,d\n", Runtime.getRuntime().freeMemory()); | 445 System.out.printf("Free mem: %,d\n", Runtime.getRuntime().freeMemory()); |
428 } | 446 } |
429 | 447 |
430 static class DoNothingManifestInspector implements HgManifest.Inspector { | 448 static class DoNothingManifestInspector implements HgManifest.Inspector { |