Mercurial > hg4j
diff src/org/tmatesoft/hg/repo/HgManifest.java @ 326:d42a45a2c9d6
Alternative tag collection approach for a file history
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 04 Oct 2011 06:28:01 +0200 |
parents | 283b294d1079 |
children | 5f9073eabf06 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgManifest.java Mon Oct 03 06:54:43 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgManifest.java Tue Oct 04 06:28:01 2011 +0200 @@ -22,6 +22,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.tmatesoft.hg.core.HgBadStateException; import org.tmatesoft.hg.core.Nodeid; @@ -124,19 +126,8 @@ if (inspector == null || localRevisions == null) { throw new IllegalArgumentException(); } - int[] manifestLocalRevs = new int[localRevisions.length]; - boolean needsSort = false; - for (int i = 0; i < localRevisions.length; i++) { - final int manifestLocalRev = fromChangelog(localRevisions[i]); - manifestLocalRevs[i] = manifestLocalRev; - if (i > 0 && manifestLocalRevs[i-1] > manifestLocalRev) { - needsSort = true; - } - } - if (needsSort) { - Arrays.sort(manifestLocalRevs); - } - content.iterate(manifestLocalRevs, true, new ManifestParser(inspector)); + int[] localManifestRevs = toLocalManifestRevisions(localRevisions); + content.iterate(localManifestRevs, true, new ManifestParser(inspector)); } // manifest revision number that corresponds to the given changeset @@ -158,15 +149,22 @@ /** * Extracts file revision as it was known at the time of given changeset. * - * @param revisionNumber local changeset index + * @param localChangelogRevision local changeset index * @param file path to file in question * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file */ - @Experimental(reason="Perhaps, HgDataFile shall own this method") - public Nodeid getFileRevision(int revisionNumber, final Path file) { - int rev = fromChangelog(revisionNumber); - final Nodeid[] rv = new Nodeid[] { null }; - content.iterate(rev, rev, true, new RevlogStream.Inspector() { + @Experimental(reason="Perhaps, HgDataFile shall own this method, or get a delegate?") + public Nodeid getFileRevision(int localChangelogRevision, final Path file) { + return getFileRevisions(file, localChangelogRevision).get(localChangelogRevision); + } + + // XXX package-local, IntMap, and HgDataFile getFileRevisionAt(int... localChangelogRevisions) + @Experimental(reason="@see #getFileRevision") + public Map<Integer, Nodeid> getFileRevisions(final Path file, int... localChangelogRevisions) { + // FIXME need tests + int[] localManifestRevisions = toLocalManifestRevisions(localChangelogRevisions); + final HashMap<Integer,Nodeid> rv = new HashMap<Integer, Nodeid>(localChangelogRevisions.length); + content.iterate(localManifestRevisions, true, new RevlogStream.Inspector() { public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -181,8 +179,10 @@ if (file.toString().equals(fname)) { byte[] nid = new byte[40]; data.readBytes(nid, 0, 40); - rv[0] = Nodeid.fromAscii(nid, 0, 40); + rv.put(linkRevision, Nodeid.fromAscii(nid, 0, 40)); break; + } else { + data.skip(40); } // else skip to the end of line while (!data.isEmpty() && (b = data.readByte()) != '\n') @@ -194,9 +194,26 @@ } } }); - return rv[0]; + return rv; } - + + + private int[] toLocalManifestRevisions(int[] localChangelogRevisions) { + int[] localManifestRevs = new int[localChangelogRevisions.length]; + boolean needsSort = false; + for (int i = 0; i < localChangelogRevisions.length; i++) { + final int manifestLocalRev = fromChangelog(localChangelogRevisions[i]); + localManifestRevs[i] = manifestLocalRev; + if (i > 0 && localManifestRevs[i-1] > manifestLocalRev) { + needsSort = true; + } + } + if (needsSort) { + Arrays.sort(localManifestRevs); + } + return localManifestRevs; + } + public interface Inspector { boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision); /** @@ -211,7 +228,7 @@ public interface Inspector2 extends Inspector { boolean next(Nodeid nid, Path fname, Flags flags); } - + /** * When Pool uses Strings directly, * ManifestParser creates new String instance with new char[] value, and does byte->char conversion.