Mercurial > hg4j
changeset 233:1d389c0cb0a5
Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 03 Jun 2011 04:50:09 +0200 |
parents | b7347daa50e3 |
children | b2cfbe46f9b6 |
files | cmdline/org/tmatesoft/hg/console/Main.java src/org/tmatesoft/hg/repo/HgDataFile.java |
diffstat | 2 files changed, 51 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Main.java Thu Jun 02 05:13:39 2011 +0200 +++ b/cmdline/org/tmatesoft/hg/console/Main.java Fri Jun 03 04:50:09 2011 +0200 @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; +import org.tmatesoft.hg.core.HgLogCommand; import org.tmatesoft.hg.core.HgLogCommand.FileRevision; import org.tmatesoft.hg.core.HgCatCommand; import org.tmatesoft.hg.core.HgFileRevision; @@ -32,6 +33,7 @@ import org.tmatesoft.hg.internal.DigestHelper; import org.tmatesoft.hg.internal.PathGlobMatcher; import org.tmatesoft.hg.repo.HgBranches; +import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgInternals; import org.tmatesoft.hg.repo.HgManifest; @@ -40,6 +42,7 @@ import org.tmatesoft.hg.repo.HgStatusCollector; import org.tmatesoft.hg.repo.HgStatusInspector; import org.tmatesoft.hg.repo.HgWorkingCopyStatusCollector; +import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; import org.tmatesoft.hg.util.Path; /** @@ -65,7 +68,8 @@ public static void main(String[] args) throws Exception { Main m = new Main(args); - m.testCatAtCsetRevision(); + m.testEffectiveFileLog(); +// m.testCatAtCsetRevision(); // m.testMergeState(); // m.testFileStatus(); // m.dumpBranches(); @@ -79,6 +83,20 @@ // m.bunchOfTests(); } + private void testEffectiveFileLog() { + for (String fname : cmdLineOpts.getList("")) { + System.out.println(fname); + HgDataFile fn = hgRepo.getFileNode(fname); + if (fn.exists()) { + fn.history(new HgChangelog.Inspector() { + public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) { + System.out.printf("%d:%s\n", revisionNumber, nodeid); + } + }); + } + } + } + // TODO as test in TestCat private void testCatAtCsetRevision() throws Exception { HgCatCommand cmd = new HgCatCommand(hgRepo); @@ -112,7 +130,7 @@ // final Path path = Path.create("src/org/tmatesoft/hg/internal/Experimental.java"); // final Path path = Path.create("missing-dir/"); // HgWorkingCopyStatusCollector wcsc = HgWorkingCopyStatusCollector.create(hgRepo, path); - HgWorkingCopyStatusCollector wcsc = HgWorkingCopyStatusCollector.create(hgRepo, new PathGlobMatcher("missing-dir/**/*")); + HgWorkingCopyStatusCollector wcsc = HgWorkingCopyStatusCollector.create(hgRepo, new PathGlobMatcher("mi**")); wcsc.walk(TIP, new StatusDump()); }
--- a/src/org/tmatesoft/hg/repo/HgDataFile.java Thu Jun 02 05:13:39 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgDataFile.java Fri Jun 03 04:50:09 2011 +0200 @@ -176,7 +176,37 @@ } }; content.iterate(start, end, false, insp); - getRepo().getChangelog().range(inspector, commitRevisions); + final HgChangelog changelog = getRepo().getChangelog(); +// changelog.range(inspector, commitRevisions); not effective when changes are sparse and far from each other + // + final int HistoricallyCloseCommits = 50; // XXX perhaps, shall increase/decrease based on changelog.revisionCount() + // (huge changelog => memory mapped files, each file re-read is more expensive than iterating over records in one read? + // + // try short sequences on neighboring revisions. + for (int i = 0; i < commitRevisions.length; ) { + int x = i; + i++; + boolean sequential = true; + while (i < commitRevisions.length) { + if (commitRevisions[i] == commitRevisions[i-1] + 1) { + i++; + } else if (commitRevisions[i] - commitRevisions[i-1] < HistoricallyCloseCommits) { + // close enough, but not sequential + sequential = false; + i++; + } else { + break; + } + } + if (sequential) { + // commitRevisions[x..i-1] are sequential + changelog.range(commitRevisions[x], commitRevisions[i-1], inspector); + } else { + int[] revs = new int[i-x]; + System.arraycopy(commitRevisions, x, revs, 0, i-x); + changelog.range(inspector, revs); + } + } } // for a given local revision of the file, find out local revision in the changelog