Mercurial > hg4j
diff src/org/tmatesoft/hg/repo/HgStatusCollector.java @ 248:3fbfce107f94
Issue 8: Means to find out information about given file at specific changeset. Inner ManifestRevisionInspector got promoted to ManifestRevision
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 12 Aug 2011 18:48:57 +0200 |
parents | 1ec6b327a6ac |
children | 81e9a3c9bafe |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgStatusCollector.java Fri Aug 12 17:17:37 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgStatusCollector.java Fri Aug 12 18:48:57 2011 +0200 @@ -31,6 +31,7 @@ import org.tmatesoft.hg.core.HgDataStreamException; import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.internal.ManifestRevision; import org.tmatesoft.hg.internal.Pool; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathPool; @@ -46,7 +47,7 @@ public class HgStatusCollector { private final HgRepository repo; - private final SortedMap<Integer, ManifestRevisionInspector> cache; // sparse array, in fact + private final SortedMap<Integer, ManifestRevision> cache; // sparse array, in fact // with cpython repository, ~70 000 changes, complete Log (direct out, no reverse) output // no cache limit, no nodeids and fname caching - OOME on changeset 1035 // no cache limit, but with cached nodeids and filenames - 1730+ @@ -55,17 +56,17 @@ private PathPool pathPool; private final Pool<Nodeid> cacheNodes; private final Pool<String> cacheFilenames; // XXX in fact, need to think if use of PathPool directly instead is better solution - private final ManifestRevisionInspector emptyFakeState; + private final ManifestRevision emptyFakeState; private Path.Matcher scope = new Path.Matcher.Any(); public HgStatusCollector(HgRepository hgRepo) { this.repo = hgRepo; - cache = new TreeMap<Integer, ManifestRevisionInspector>(); + cache = new TreeMap<Integer, ManifestRevision>(); cacheNodes = new Pool<Nodeid>(); cacheFilenames = new Pool<String>(); - emptyFakeState = new ManifestRevisionInspector(null, null); + emptyFakeState = new ManifestRevision(null, null); emptyFakeState.begin(-1, null, -1); emptyFakeState.end(-1); } @@ -74,8 +75,8 @@ return repo; } - private ManifestRevisionInspector get(int rev) { - ManifestRevisionInspector i = cache.get(rev); + private ManifestRevision get(int rev) { + ManifestRevision i = cache.get(rev); if (i == null) { if (rev == -1) { return emptyFakeState; @@ -84,7 +85,7 @@ // assume usually we go from oldest to newest, hence remove oldest as most likely to be no longer necessary cache.remove(cache.firstKey()); } - i = new ManifestRevisionInspector(cacheNodes, cacheFilenames); + i = new ManifestRevision(cacheNodes, cacheFilenames); cache.put(rev, i); repo.getManifest().walk(rev, rev, i); } @@ -101,7 +102,7 @@ cache.remove(cache.firstKey()); } repo.getManifest().walk(minRev, maxRev, new HgManifest.Inspector() { - private ManifestRevisionInspector delegate; + private ManifestRevision delegate; private boolean cacheHit; // range may include revisions we already know about, do not re-create them public boolean begin(int manifestRevision, Nodeid nid, int changelogRevision) { @@ -109,7 +110,7 @@ if (cache.containsKey(changelogRevision)) { // don't need to check emptyFakeState hit as revision never -1 here cacheHit = true; } else { - cache.put(changelogRevision, delegate = new ManifestRevisionInspector(cacheNodes, cacheFilenames)); + cache.put(changelogRevision, delegate = new ManifestRevision(cacheNodes, cacheFilenames)); // cache may grow bigger than max size here, but it's ok as present simplistic cache clearing mechanism may // otherwise remove entries we just added delegate.begin(manifestRevision, nid, changelogRevision); @@ -136,7 +137,7 @@ }); } - /*package-local*/ ManifestRevisionInspector raw(int rev) { + /*package-local*/ ManifestRevision raw(int rev) { return get(rev); } /*package-local*/ PathPool getPathPool() { @@ -193,7 +194,7 @@ } // in fact, rev1 and rev2 are often next (or close) to each other, // thus, we can optimize Manifest reads here (manifest.walk(rev1, rev2)) - ManifestRevisionInspector r1, r2 ; + ManifestRevision r1, r2 ; boolean need1 = !cached(rev1), need2 = !cached(rev2); if (need1 || need2) { int minRev, maxRev; @@ -422,60 +423,5 @@ return l; } } - - /*package-local*/ static final class ManifestRevisionInspector implements HgManifest.Inspector { - private final TreeMap<String, Nodeid> idsMap; - private final TreeMap<String, String> flagsMap; - private final Pool<Nodeid> idsPool; - private final Pool<String> namesPool; - - // optional pools for effective management of nodeids and filenames (they are likely - // to be duplicated among different manifest revisions - public ManifestRevisionInspector(Pool<Nodeid> nodeidPool, Pool<String> filenamePool) { - idsPool = nodeidPool; - namesPool = filenamePool; - idsMap = new TreeMap<String, Nodeid>(); - flagsMap = new TreeMap<String, String>(); - } - - public Collection<String> files() { - return idsMap.keySet(); - } - - public Nodeid nodeid(String fname) { - return idsMap.get(fname); - } - - public String flags(String fname) { - return flagsMap.get(fname); - } - - // - - public boolean next(Nodeid nid, String fname, String flags) { - if (namesPool != null) { - fname = namesPool.unify(fname); - } - if (idsPool != null) { - nid = idsPool.unify(nid); - } - idsMap.put(fname, nid); - if (flags != null) { - // TreeMap$Entry takes 32 bytes. No reason to keep null for such price - // Perhaps, Map<String, Pair<Nodeid, String>> might be better solution - flagsMap.put(fname, flags); - } - return true; - } - - public boolean end(int revision) { - // in fact, this class cares about single revision - return false; - } - - public boolean begin(int revision, Nodeid nid, int changelogRevision) { - return true; - } - } }