comparison src/org/tmatesoft/hg/core/HgAnnotateCommand.java @ 676:3219cfadda49

Switch to alternative annotate producer (walks from parents to children). Refactor FileAnnotation to match updated annotate approach
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 18 Jul 2013 18:03:51 +0200
parents 5f52074707b2
children 1c49c0cee540
comparison
equal deleted inserted replaced
675:a20121a2bba6 676:3219cfadda49
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.core; 17 package org.tmatesoft.hg.core;
18 18
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
20
21 import java.util.Arrays;
22
23 import org.tmatesoft.hg.core.HgBlameInspector.BlockData;
24 import org.tmatesoft.hg.internal.Callback; 19 import org.tmatesoft.hg.internal.Callback;
25 import org.tmatesoft.hg.internal.CsetParamKeeper; 20 import org.tmatesoft.hg.internal.CsetParamKeeper;
26 import org.tmatesoft.hg.internal.FileAnnotation; 21 import org.tmatesoft.hg.internal.ForwardAnnotateInspector;
27 import org.tmatesoft.hg.internal.FileAnnotation.LineDescriptor;
28 import org.tmatesoft.hg.internal.FileAnnotation.LineInspector;
29 import org.tmatesoft.hg.repo.HgDataFile; 22 import org.tmatesoft.hg.repo.HgDataFile;
30 import org.tmatesoft.hg.repo.HgRepository; 23 import org.tmatesoft.hg.repo.HgRepository;
31 import org.tmatesoft.hg.repo.HgRuntimeException; 24 import org.tmatesoft.hg.repo.HgRuntimeException;
32 import org.tmatesoft.hg.util.CancelSupport; 25 import org.tmatesoft.hg.util.CancelSupport;
33 import org.tmatesoft.hg.util.CancelledException; 26 import org.tmatesoft.hg.util.CancelledException;
86 followRename = followCopyRename; 79 followRename = followCopyRename;
87 return this; 80 return this;
88 } 81 }
89 82
90 // TODO [post-1.1] set encoding and provide String line content from LineInfo 83 // TODO [post-1.1] set encoding and provide String line content from LineInfo
84 // TODO FWIW: diff algorithms: http://bramcohen.livejournal.com/73318.html
91 85
92 /** 86 /**
93 * Annotate selected file 87 * Annotate selected file
94 * 88 *
95 * @param inspector 89 * @param inspector
105 throw new HgBadArgumentException("Command needs file argument", null); 99 throw new HgBadArgumentException("Command needs file argument", null);
106 } 100 }
107 final ProgressSupport progress = getProgressSupport(inspector); 101 final ProgressSupport progress = getProgressSupport(inspector);
108 final CancelSupport cancellation = getCancelSupport(inspector, true); 102 final CancelSupport cancellation = getCancelSupport(inspector, true);
109 cancellation.checkCancelled(); 103 cancellation.checkCancelled();
110 progress.start(2); 104 progress.start(200);
111 try { 105 try {
112 HgDataFile df = repo.getFileNode(file); 106 HgDataFile df = repo.getFileNode(file);
113 if (!df.exists()) { 107 if (!df.exists()) {
114 return; 108 return;
115 } 109 }
116 final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0); 110 final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0);
117 Collector c = new Collector(cancellation); 111 final int annotateRevIndex = annotateRevision.get();
118 FileAnnotation fa = new FileAnnotation(c); 112 HgDiffCommand cmd = new HgDiffCommand(repo).file(df);
119 HgDiffCommand cmd = new HgDiffCommand(repo); 113 cmd.range(changesetStart, annotateRevIndex);
120 cmd.file(df).order(HgIterateDirection.NewToOld); 114 cmd.set(cancellation);
121 cmd.range(changesetStart, annotateRevision.get()); 115 cmd.set(new ProgressSupport.Sub(progress, 100));
122 cmd.executeAnnotate(fa); 116 //
123 progress.worked(1); 117 // ReverseAnnotateInspector ai = new ReverseAnnotateInspector();
124 c.throwIfCancelled(); 118 ForwardAnnotateInspector ai = new ForwardAnnotateInspector();
119 cmd.order(ai.iterateDirection());
120 //
121 cmd.executeAnnotate(ai);
125 cancellation.checkCancelled(); 122 cancellation.checkCancelled();
126 ProgressSupport.Sub subProgress = new ProgressSupport.Sub(progress, 1); 123 ai.report(annotateRevIndex, inspector, new ProgressSupport.Sub(progress, 100), cancellation);
127 subProgress.start(c.lineRevisions.length);
128 LineImpl li = new LineImpl();
129 for (int i = 0; i < c.lineRevisions.length; i++) {
130 li.init(i+1, c.lineRevisions[i], c.line(i));
131 inspector.next(li);
132 subProgress.worked(1);
133 cancellation.checkCancelled();
134 }
135 subProgress.done();
136 } catch (HgRuntimeException ex) { 124 } catch (HgRuntimeException ex) {
137 throw new HgLibraryFailureException(ex); 125 throw new HgLibraryFailureException(ex);
138 } 126 }
139 progress.done(); 127 progress.done();
140 } 128 }
157 public interface LineInfo { 145 public interface LineInfo {
158 int getLineNumber(); 146 int getLineNumber();
159 int getChangesetIndex(); 147 int getChangesetIndex();
160 byte[] getContent(); 148 byte[] getContent();
161 } 149 }
162
163 // TODO [post-1.1] there's no need in FileAnnotation.LineInspector, merge it here
164 // ok for 1.1 as this LineInspector is internal class
165 private static class Collector implements LineInspector {
166 private int[] lineRevisions;
167 private byte[][] lines;
168 private final CancelSupport cancelSupport;
169 private CancelledException cancelEx;
170
171 Collector(CancelSupport cancellation) {
172 cancelSupport = cancellation;
173 }
174
175 public void line(int lineNumber, int changesetRevIndex, BlockData lineContent, LineDescriptor ld) {
176 if (cancelEx != null) {
177 return;
178 }
179 if (lineRevisions == null) {
180 lineRevisions = new int [ld.totalLines()];
181 Arrays.fill(lineRevisions, NO_REVISION);
182 lines = new byte[ld.totalLines()][];
183 }
184 lineRevisions[lineNumber] = changesetRevIndex;
185 lines[lineNumber] = lineContent.asArray();
186 try {
187 cancelSupport.checkCancelled();
188 } catch (CancelledException ex) {
189 cancelEx = ex;
190 }
191 }
192
193 public byte[] line(int i) {
194 return lines[i];
195 }
196
197 public void throwIfCancelled() throws CancelledException {
198 if (cancelEx != null) {
199 throw cancelEx;
200 }
201 }
202 }
203
204
205 private static class LineImpl implements LineInfo {
206 private int ln;
207 private int rev;
208 private byte[] content;
209
210 void init(int line, int csetRev, byte[] cnt) {
211 ln = line;
212 rev = csetRev;
213 content = cnt;
214 }
215
216 public int getLineNumber() {
217 return ln;
218 }
219
220 public int getChangesetIndex() {
221 return rev;
222 }
223
224 public byte[] getContent() {
225 return content;
226 }
227 }
228 } 150 }