Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/MapTagsToFileRevisions.java @ 254:a620f0663a37
Collect tags for a file - improve performance of 'sparse' manifest reads
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 16 Aug 2011 04:03:29 +0200 |
parents | |
children | 5a6ab50b4cbf |
comparison
equal
deleted
inserted
replaced
253:1874d11054e5 | 254:a620f0663a37 |
---|---|
1 package org.tmatesoft.hg.test; | |
2 | |
3 import java.io.*; | |
4 import java.util.*; | |
5 import java.util.Map.Entry; | |
6 | |
7 import org.tmatesoft.hg.core.*; | |
8 import org.tmatesoft.hg.internal.Pool; | |
9 import org.tmatesoft.hg.repo.*; | |
10 import org.tmatesoft.hg.repo.HgTags.TagInfo; | |
11 import org.tmatesoft.hg.util.*; | |
12 | |
13 /** | |
14 * @author Marc Strapetz | |
15 */ | |
16 public class MapTagsToFileRevisions { | |
17 | |
18 // Static ================================================================= | |
19 | |
20 public static void main(String[] args) throws HgException, CancelledException { | |
21 final long start = System.currentTimeMillis(); | |
22 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | |
23 final HgTags tags = repository.getTags(); | |
24 // | |
25 // build cache | |
26 final Map<String, Map<TagInfo, Nodeid>> file2tag2rev = new HashMap<String, Map<TagInfo, Nodeid>>(); | |
27 System.out.printf("Collecting manifests for %d tags\n", tags.getTags().size()); | |
28 // effective translation of changeset revisions to their local indexes | |
29 final HgChangelog.RevisionMap clogrmap = repository.getChangelog().new RevisionMap().init(); | |
30 int[] tagLocalRevs = new int[tags.getTags().size()]; | |
31 int i = 0; | |
32 for (TagInfo tag : tags.getTags().values()) { | |
33 final Nodeid tagRevision = tag.revision(); | |
34 int tagLocalRev = clogrmap.localRevision(tagRevision); | |
35 tagLocalRevs[i++] = tagLocalRev; | |
36 } | |
37 System.out.printf("Found tag revisions to analyze: %d\n", System.currentTimeMillis() - start); | |
38 // | |
39 repository.getManifest().walk(new HgManifest.Inspector() { | |
40 private List<String> tagsAtRev; | |
41 final Pool<String> filenamePool = new Pool<String>(); | |
42 final Pool<Nodeid> nodeidPool = new Pool<Nodeid>(); | |
43 | |
44 public boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision) { | |
45 Nodeid cset = clogrmap.revision(changelogRevision); | |
46 tagsAtRev = tags.tags(cset); | |
47 if (tagsAtRev.isEmpty()) { | |
48 System.out.println("Can't happen, provided we iterate over revisions with tags only"); | |
49 } | |
50 return true; | |
51 } | |
52 | |
53 public boolean next(Nodeid nid, String fname, String flags) { | |
54 fname = filenamePool.unify(fname); | |
55 nid = nodeidPool.unify(nid); | |
56 Map<TagInfo, Nodeid> m = file2tag2rev.get(fname); | |
57 if (m == null) { | |
58 file2tag2rev.put(fname, m = new HashMap<TagInfo, Nodeid>()); | |
59 } | |
60 for (String tag : tagsAtRev) { | |
61 m.put(tags.getTags().get(tag), nid); | |
62 } | |
63 return true; | |
64 } | |
65 | |
66 public boolean end(int manifestRevision) { | |
67 return true; | |
68 } | |
69 | |
70 }, tagLocalRevs); | |
71 System.out.printf("Cache built: %d\n", System.currentTimeMillis() - start); | |
72 // | |
73 // look up specific file. This part is fast. | |
74 final Path targetPath = Path.create("README"); | |
75 HgDataFile fileNode = repository.getFileNode(targetPath); | |
76 // TODO if fileNode.isCopy, repeat for each getCopySourceName() | |
77 for (int localFileRev = 0; localFileRev < fileNode.getRevisionCount(); localFileRev++) { | |
78 Nodeid fileRev = fileNode.getRevision(localFileRev); | |
79 int changesetLocalRev = fileNode.getChangesetLocalRevision(localFileRev); | |
80 List<String> associatedTags = new LinkedList<String>(); | |
81 final Map<TagInfo, Nodeid> allTagsOfTheFile = file2tag2rev.get(targetPath.toString()); | |
82 for (Entry<TagInfo, Nodeid> e : allTagsOfTheFile.entrySet()) { | |
83 Nodeid fileRevAtTag = e.getValue(); | |
84 if (fileRev.equals(fileRevAtTag)) { | |
85 associatedTags.add(e.getKey().name()); | |
86 } | |
87 } | |
88 System.out.printf("%3d%7d%s\n", localFileRev, changesetLocalRev, associatedTags); | |
89 } | |
90 System.out.printf("Total time: %d", System.currentTimeMillis() - start); | |
91 } | |
92 | |
93 public static void main2(String[] args) throws HgException, CancelledException { | |
94 final HgRepository repository = new HgLookup().detect(new File("/temp/hg/cpython")); | |
95 final Path targetPath = Path.create("README"); | |
96 final HgTags tags = repository.getTags(); | |
97 final Map<String, HgTags.TagInfo> tagToInfo = tags.getTags(); | |
98 final HgManifest manifest = repository.getManifest(); | |
99 final Map<Nodeid, List<String>> changeSetRevisionToTags = new HashMap<Nodeid, List<String>>(); | |
100 final HgDataFile fileNode = repository.getFileNode(targetPath); | |
101 for (String tagName : tagToInfo.keySet()) { | |
102 final HgTags.TagInfo info = tagToInfo.get(tagName); | |
103 final Nodeid nodeId = info.revision(); | |
104 // TODO: This is not correct as we can't be sure that file at the corresponding revision is actually our target file (which may have been renamed, etc.) | |
105 final Nodeid fileRevision = manifest.getFileRevision(repository.getChangelog().getLocalRevision(nodeId), targetPath); | |
106 if (fileRevision == null) { | |
107 continue; | |
108 } | |
109 | |
110 final Nodeid changeSetRevision = fileNode.getChangesetRevision(fileRevision); | |
111 List<String> revisionTags = changeSetRevisionToTags.get(changeSetRevision); | |
112 if (revisionTags == null) { | |
113 revisionTags = new ArrayList<String>(); | |
114 changeSetRevisionToTags.put(changeSetRevision, revisionTags); | |
115 } | |
116 revisionTags.add(tagName); | |
117 } | |
118 | |
119 final HgLogCommand logCommand = new HgLogCommand(repository); | |
120 logCommand.file(targetPath, true); | |
121 logCommand.execute(new HgChangesetHandler() { | |
122 public void next(HgChangeset changeset) { | |
123 if (changeset.getAffectedFiles().contains(targetPath)) { | |
124 System.out.println(changeset.getRevision() + " " + changeSetRevisionToTags.get(changeset.getNodeid())); | |
125 } | |
126 } | |
127 }); | |
128 } | |
129 } |