Mercurial > jhg
diff src/org/tmatesoft/hg/internal/FileRenameHistory.java @ 694:7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 17:42:10 +0200 |
parents | 72fc7774b87e |
children |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/FileRenameHistory.java Mon Aug 05 12:45:36 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/FileRenameHistory.java Mon Aug 05 17:42:10 2013 +0200 @@ -16,7 +16,10 @@ */ package org.tmatesoft.hg.internal; +import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -24,6 +27,8 @@ import org.tmatesoft.hg.core.HgFileRevision; import org.tmatesoft.hg.core.HgIterateDirection; import org.tmatesoft.hg.repo.HgDataFile; +import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.repo.HgRuntimeException; /** * Traces file renames. Quite similar to HgChangesetFileSneaker, although the latter tries different paths @@ -61,8 +66,9 @@ LinkedList<Chunk> chunks = new LinkedList<Chunk>(); int chunkStart = 0, chunkEnd = fileRev; int csetChunkEnd = -1, csetChunkStart = -1; + BasicRevMap csetMap = new BasicRevMap(0, fileRev).collect(df); while (fileRev >= 0) { - int cset = df.getChangesetRevisionIndex(fileRev); + int cset = csetMap.changesetAt(fileRev); if (csetChunkEnd == -1) { csetChunkEnd = cset; } @@ -82,6 +88,7 @@ HgFileRevision origin = df.getCopySource(fileRev); df = df.getRepo().getFileNode(origin.getPath()); fileRev = chunkEnd = df.getRevisionIndex(origin.getRevision()); + csetMap = new BasicRevMap(0, fileRev).collect(df); chunkStart = 0; csetChunkEnd = cset - 1; // if df is copy, cset can't be 0 csetChunkStart = -1; @@ -130,7 +137,7 @@ /** * file has changes [firstFileRev..lastFileRev] that have occurred somewhere in [firstCset..lastCset] */ - public static class Chunk { + public static final class Chunk { private final HgDataFile df; private final int fileRevFrom; private final int fileRevTo; @@ -159,4 +166,32 @@ return csetTo; } } + + private static final class BasicRevMap implements HgDataFile.LinkRevisionInspector { + private final int[] revs; + private final int fromRev; + private final int toRev; + public BasicRevMap(int startRev, int endRev) { + revs = new int[endRev+1]; // for simplicity, just ignore startRev now (it's 0 in local use anyway) + fromRev = startRev; + toRev = endRev; + Arrays.fill(revs, BAD_REVISION); + } + + public BasicRevMap collect(HgDataFile df) { + df.indexWalk(fromRev, toRev, this); + return this; + } + + public void next(int revisionIndex, int linkedRevisionIndex) throws HgRuntimeException { + revs[revisionIndex] = linkedRevisionIndex; + } + + /** + * @return {@link HgRepository#BAD_REVISION} if there's no mapping + */ + public int changesetAt(int rev) { + return revs[rev]; + } + } }