Mercurial > jhg
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 } | 
