Mercurial > hg4j
comparison src/org/tmatesoft/hg/internal/BlameHelper.java @ 625:b4948b159ab1
Refactor internals of blame support, tests
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 21 May 2013 17:24:22 +0200 |
parents | 707b5c7c6fa4 |
children | 6526d8adbc0f |
comparison
equal
deleted
inserted
replaced
624:507602cb4fb3 | 625:b4948b159ab1 |
---|---|
14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
16 */ | 16 */ |
17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
18 | 18 |
19 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; | |
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | 20 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; |
20 | 21 |
21 import java.util.LinkedList; | 22 import java.util.LinkedList; |
22 import java.util.ListIterator; | 23 import java.util.ListIterator; |
23 | 24 |
46 public class BlameHelper { | 47 public class BlameHelper { |
47 | 48 |
48 private final HgBlameInspector insp; | 49 private final HgBlameInspector insp; |
49 private FileLinesCache linesCache; | 50 private FileLinesCache linesCache; |
50 | 51 |
51 // FIXME exposing internals (use of FileLinesCache through cons arg and #useFileUpTo) smells bad, refactor! | 52 public BlameHelper(HgBlameInspector inspector) { |
52 | |
53 public BlameHelper(HgBlameInspector inspector, int cacheHint) { | |
54 insp = inspector; | 53 insp = inspector; |
54 } | |
55 | |
56 /** | |
57 * Build history of the file for the specified range (follow renames if necessary). This history | |
58 * is used to access various file revision data during subsequent {@link #diff(int, int, int, int)} and | |
59 * {@link #annotateChange(int, int, int[], int[])} calls. Callers can use returned history for own approaches | |
60 * to iteration over file history. | |
61 | |
62 * <p>NOTE, clogRevIndexEnd has to list name of the supplied file in the corresponding manifest, | |
63 * as it's not possible to trace rename history otherwise. | |
64 */ | |
65 public FileHistory prepare(HgDataFile df, int clogRevIndexStart, int clogRevIndexEnd) { | |
66 assert clogRevIndexStart <= clogRevIndexEnd; | |
67 FileHistory fileHistory = new FileHistory(df, clogRevIndexStart, clogRevIndexEnd); | |
68 fileHistory.build(); | |
69 int cacheHint = 5; // cache comes useful when we follow merge branches and don't want to | |
70 // parse base revision twice. There's no easy way to determine max(distance(all(base,merge))), | |
71 // hence the heuristics to use the longest history chunk: | |
72 for (FileRevisionHistoryChunk c : fileHistory.iterate(OldToNew)) { | |
73 // iteration order is not important here | |
74 if (c.revisionCount() > cacheHint) { | |
75 cacheHint = c.revisionCount(); | |
76 } | |
77 } | |
55 linesCache = new FileLinesCache(cacheHint); | 78 linesCache = new FileLinesCache(cacheHint); |
56 } | 79 for (FileRevisionHistoryChunk fhc : fileHistory.iterate(OldToNew)) { |
57 | 80 // iteration order is not important here |
58 public void useFileUpTo(HgDataFile df, int clogRevIndex) { | 81 linesCache.useFileUpTo(fhc.getFile(), fhc.getEndChangeset()); |
59 linesCache.useFileUpTo(df, clogRevIndex); | 82 } |
83 return fileHistory; | |
60 } | 84 } |
61 | 85 |
62 // NO_REVISION is not allowed as any argument | 86 // NO_REVISION is not allowed as any argument |
63 public void diff(int fileRevIndex1, int clogRevIndex1, int fileRevIndex2, int clogRevIndex2) throws HgCallbackTargetException { | 87 public void diff(int fileRevIndex1, int clogRevIndex1, int fileRevIndex2, int clogRevIndex2) throws HgCallbackTargetException { |
64 HgDataFile targetFile = linesCache.getFile(clogRevIndex2); | 88 HgDataFile targetFile = linesCache.getFile(clogRevIndex2); |
114 private static class FileLinesCache { | 138 private static class FileLinesCache { |
115 private final LinkedList<Pair<Integer, LineSequence>> lruCache; | 139 private final LinkedList<Pair<Integer, LineSequence>> lruCache; |
116 private final int limit; | 140 private final int limit; |
117 private final LinkedList<Pair<Integer, HgDataFile>> files; // TODO in fact, need sparse array | 141 private final LinkedList<Pair<Integer, HgDataFile>> files; // TODO in fact, need sparse array |
118 | 142 |
143 /** | |
144 * @param lruLimit how many parsed file revisions to keep | |
145 */ | |
119 public FileLinesCache(int lruLimit) { | 146 public FileLinesCache(int lruLimit) { |
120 limit = lruLimit; | 147 limit = lruLimit; |
121 lruCache = new LinkedList<Pair<Integer, LineSequence>>(); | 148 lruCache = new LinkedList<Pair<Integer, LineSequence>>(); |
122 files = new LinkedList<Pair<Integer,HgDataFile>>(); | 149 files = new LinkedList<Pair<Integer,HgDataFile>>(); |
123 } | 150 } |