# HG changeset patch # User Artem Tikhomirov # Date 1307069409 -7200 # Node ID 1d389c0cb0a5ef03d4249aeffb2fdebba9dcb1e7 # Parent b7347daa50e33f93c836e7d0eafe851015c5f4d9 Optimize file history walk not to iterat over whole changelog for sparse and distant revisions diff -r b7347daa50e3 -r 1d389c0cb0a5 cmdline/org/tmatesoft/hg/console/Main.java --- 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()); } diff -r b7347daa50e3 -r 1d389c0cb0a5 src/org/tmatesoft/hg/repo/HgDataFile.java --- 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