comparison src/org/tmatesoft/hg/repo/Revlog.java @ 628:6526d8adbc0f

Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 22 May 2013 15:52:31 +0200
parents e1b29756f901
children 32b0d19e8aba
comparison
equal deleted inserted replaced
627:5153eb73b18d 628:6526d8adbc0f
92 return repo; 92 return repo;
93 } 93 }
94 94
95 /** 95 /**
96 * @return total number of revisions kept in this revlog 96 * @return total number of revisions kept in this revlog
97 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 97 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
98 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
98 */ 99 */
99 public final int getRevisionCount() throws HgRuntimeException { 100 public final int getRevisionCount() throws HgRuntimeException {
100 return content.revisionCount(); 101 return content.revisionCount();
101 } 102 }
102 103
103 /** 104 /**
104 * @return index of last known revision, a.k.a. {@link HgRepository#TIP}, or {@link HgRepository#NO_REVISION} if revlog is empty 105 * @return index of last known revision, a.k.a. {@link HgRepository#TIP}, or {@link HgRepository#NO_REVISION} if revlog is empty
105 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 106 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
107 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
106 */ 108 */
107 public final int getLastRevision() throws HgRuntimeException { 109 public final int getLastRevision() throws HgRuntimeException {
108 // although old code gives correct result when revlog is empty (NO_REVISION deliberately == -1), 110 // although old code gives correct result when revlog is empty (NO_REVISION deliberately == -1),
109 // it's still better to be explicit 111 // it's still better to be explicit
110 int revCount = content.revisionCount(); 112 int revCount = content.revisionCount();
115 * Map revision index to unique revision identifier (nodeid). 117 * Map revision index to unique revision identifier (nodeid).
116 * 118 *
117 * @param revisionIndex index of the entry in this revlog, may be {@link HgRepository#TIP} 119 * @param revisionIndex index of the entry in this revlog, may be {@link HgRepository#TIP}
118 * @return revision nodeid of the entry 120 * @return revision nodeid of the entry
119 * 121 *
120 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 122 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
123 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
124 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
121 */ 125 */
122 public final Nodeid getRevision(int revisionIndex) throws HgRuntimeException { 126 public final Nodeid getRevision(int revisionIndex) throws HgRuntimeException {
123 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it 127 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it
124 return Nodeid.fromBinary(content.nodeid(revisionIndex), 0); 128 return Nodeid.fromBinary(content.nodeid(revisionIndex), 0);
125 } 129 }
128 * Effective alternative to map few revision indexes to corresponding nodeids at once. 132 * Effective alternative to map few revision indexes to corresponding nodeids at once.
129 * <p>Note, there are few aspects to be careful about when using this method<ul> 133 * <p>Note, there are few aspects to be careful about when using this method<ul>
130 * <li>ordering of the revisions in the return list is unspecified, it's likely won't match that of the method argument 134 * <li>ordering of the revisions in the return list is unspecified, it's likely won't match that of the method argument
131 * <li>supplied array get modified (sorted)</ul> 135 * <li>supplied array get modified (sorted)</ul>
132 * @return list of mapped revisions in no particular order 136 * @return list of mapped revisions in no particular order
133 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 137 * @throws HgInvalidRevisionException if any supplied revision doesn't identify revision from this revlog. <em>Runtime exception</em>
138 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
139 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
134 */ 140 */
135 public final List<Nodeid> getRevisions(int... revisions) throws HgRuntimeException { 141 public final List<Nodeid> getRevisions(int... revisions) throws HgRuntimeException {
136 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(revisions.length); 142 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(revisions.length);
137 Arrays.sort(revisions); 143 Arrays.sort(revisions);
138 getRevisionsInternal(rv, revisions); 144 getRevisionsInternal(rv, revisions);
139 return rv; 145 return rv;
140 } 146 }
141 147
142 /*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgInvalidRevisionException, HgInvalidControlFileException { 148 /*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgRuntimeException {
143 // once I have getRevisionMap and may find out whether it is avalable from cache, 149 // once I have getRevisionMap and may find out whether it is avalable from cache,
144 // may use it, perhaps only for small number of revisions 150 // may use it, perhaps only for small number of revisions
145 content.iterate(sortedRevs, false, new RevlogStream.Inspector() { 151 content.iterate(sortedRevs, false, new RevlogStream.Inspector() {
146 152
147 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { 153 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
157 * For occasional queries, this method works with decent performance, despite its O(n/2) approach. 163 * For occasional queries, this method works with decent performance, despite its O(n/2) approach.
158 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link HgRevisionMap} may come handy. 164 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link HgRevisionMap} may come handy.
159 * 165 *
160 * @param nid revision to look up 166 * @param nid revision to look up
161 * @return revision local index in this revlog 167 * @return revision local index in this revlog
162 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 168 * @throws HgInvalidRevisionException if revision was not found in this revlog. <em>Runtime exception</em>
169 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
170 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
163 */ 171 */
164 public final int getRevisionIndex(Nodeid nid) throws HgRuntimeException { 172 public final int getRevisionIndex(Nodeid nid) throws HgRuntimeException {
165 final int revision = doFindWithCache(nid); 173 final int revision = doFindWithCache(nid);
166 if (revision == BAD_REVISION) { 174 if (revision == BAD_REVISION) {
167 // using toString() to identify revlog. HgDataFile.toString includes path, HgManifest and HgChangelog instances 175 // using toString() to identify revlog. HgDataFile.toString includes path, HgManifest and HgChangelog instances
170 throw new HgInvalidRevisionException(String.format("Can't find revision %s in %s", nid.shortNotation(), this), nid, null); 178 throw new HgInvalidRevisionException(String.format("Can't find revision %s in %s", nid.shortNotation(), this), nid, null);
171 } 179 }
172 return revision; 180 return revision;
173 } 181 }
174 182
175 private int doFindWithCache(Nodeid nid) { 183 private int doFindWithCache(Nodeid nid) throws HgRuntimeException {
176 if (useRevisionLookup) { 184 if (useRevisionLookup) {
177 if (revisionLookup == null || content.shallDropDerivedCaches()) { 185 if (revisionLookup == null || content.shallDropDerivedCaches()) {
178 content.detach(revisionLookupCleaner); 186 content.detach(revisionLookupCleaner);
179 setRevisionLookup(RevisionLookup.createFor(content)); 187 setRevisionLookup(RevisionLookup.createFor(content));
180 } 188 }
197 /** 205 /**
198 * Note, {@link Nodeid#NULL} nodeid is not reported as known in any revlog. 206 * Note, {@link Nodeid#NULL} nodeid is not reported as known in any revlog.
199 * 207 *
200 * @param nodeid 208 * @param nodeid
201 * @return <code>true</code> if revision is part of this revlog 209 * @return <code>true</code> if revision is part of this revlog
202 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 210 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
211 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
203 */ 212 */
204 public final boolean isKnown(Nodeid nodeid) throws HgRuntimeException { 213 public final boolean isKnown(Nodeid nodeid) throws HgRuntimeException {
205 final int rn = doFindWithCache(nodeid); 214 final int rn = doFindWithCache(nodeid);
206 if (BAD_REVISION == rn) { 215 if (BAD_REVISION == rn) {
207 return false; 216 return false;
217 * Access to revision data as is, equivalent to <code>rawContent(getRevisionIndex(nodeid), sink)</code> 226 * Access to revision data as is, equivalent to <code>rawContent(getRevisionIndex(nodeid), sink)</code>
218 * 227 *
219 * @param nodeid revision to retrieve 228 * @param nodeid revision to retrieve
220 * @param sink data destination 229 * @param sink data destination
221 * 230 *
222 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog 231 * @see #rawContent(int, ByteChannel)
223 * @throws HgInvalidControlFileException if access to revlog index/data entry failed 232 *
224 * @throws CancelledException if content retrieval operation was cancelled 233 * @throws CancelledException if content retrieval operation was cancelled
225 * 234 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog. <em>Runtime exception</em>
226 * @see #rawContent(int, ByteChannel) 235 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
227 */ 236 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
228 protected void rawContent(Nodeid nodeid, ByteChannel sink) throws HgInvalidControlFileException, CancelledException, HgInvalidRevisionException { 237 */
238 protected void rawContent(Nodeid nodeid, ByteChannel sink) throws CancelledException, HgRuntimeException {
229 rawContent(getRevisionIndex(nodeid), sink); 239 rawContent(getRevisionIndex(nodeid), sink);
230 } 240 }
231 241
232 /** 242 /**
233 * Access to revision data as is (decompressed, but otherwise unprocessed, i.e. not parsed for e.g. changeset or manifest entries). 243 * Access to revision data as is (decompressed, but otherwise unprocessed, i.e. not parsed for e.g. changeset or manifest entries).
234 * 244 *
235 * @param revisionIndex index of this revlog change (not a changelog revision index), non-negative. From predefined constants, only {@link HgRepository#TIP} makes sense. 245 * @param revisionIndex index of this revlog change (not a changelog revision index), non-negative. From predefined constants, only {@link HgRepository#TIP} makes sense.
236 * @param sink data destination 246 * @param sink data destination
237 * 247 *
238 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
239 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
240 * @throws CancelledException if content retrieval operation was cancelled 248 * @throws CancelledException if content retrieval operation was cancelled
241 */ 249 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog. <em>Runtime exception</em>
242 protected void rawContent(int revisionIndex, ByteChannel sink) throws HgInvalidControlFileException, CancelledException, HgInvalidRevisionException { 250 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
251 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
252 */
253 protected void rawContent(int revisionIndex, ByteChannel sink) throws CancelledException, HgRuntimeException {
243 if (sink == null) { 254 if (sink == null) {
244 throw new IllegalArgumentException(); 255 throw new IllegalArgumentException();
245 } 256 }
246 try { 257 try {
247 ContentPipe insp = new ContentPipe(sink, 0, repo.getSessionContext().getLog()); 258 ContentPipe insp = new ContentPipe(sink, 0, repo.getSessionContext().getLog());
346 final IntMap<Nodeid> missingParents = parentInsp == null || _start == 0 ? null : new IntMap<Nodeid>(16); 357 final IntMap<Nodeid> missingParents = parentInsp == null || _start == 0 ? null : new IntMap<Nodeid>(16);
347 358
348 content.iterate(_start, end, false, new RevlogStream.Inspector() { 359 content.iterate(_start, end, false, new RevlogStream.Inspector() {
349 private int i = 0; 360 private int i = 0;
350 361
351 public void next(int revisionIndex, int actualLen, int baseRevIndex, int linkRevIndex, int parent1RevIndex, int parent2RevIndex, byte[] nodeid, DataAccess data) { 362 public void next(int revisionIndex, int actualLen, int baseRevIndex, int linkRevIndex, int parent1RevIndex, int parent2RevIndex, byte[] nodeid, DataAccess data) throws HgRuntimeException {
352 Nodeid nid = Nodeid.fromBinary(nodeid, 0); 363 Nodeid nid = Nodeid.fromBinary(nodeid, 0);
353 if (revisionInsp != null) { 364 if (revisionInsp != null) {
354 revisionInsp.next(revisionIndex, nid, linkRevIndex); 365 revisionInsp.next(revisionIndex, nid, linkRevIndex);
355 } 366 }
356 if (parentInsp != null) { 367 if (parentInsp != null) {
415 public interface Inspector { 426 public interface Inspector {
416 } 427 }
417 428
418 @Experimental 429 @Experimental
419 public interface RevisionInspector extends Inspector { 430 public interface RevisionInspector extends Inspector {
420 void next(int revisionIndex, Nodeid revision, int linkedRevisionIndex); 431 void next(int revisionIndex, Nodeid revision, int linkedRevisionIndex) throws HgRuntimeException;
421 } 432 }
422 433
423 @Experimental 434 @Experimental
424 public interface ParentInspector extends Inspector { 435 public interface ParentInspector extends Inspector {
425 // XXX document whether parentX is -1 or a constant (BAD_REVISION? or dedicated?) 436 // XXX document whether parentX is -1 or a constant (BAD_REVISION? or dedicated?)
426 void next(int revisionIndex, Nodeid revision, int parent1, int parent2, Nodeid nidParent1, Nodeid nidParent2); 437 void next(int revisionIndex, Nodeid revision, int parent1, int parent2, Nodeid nidParent1, Nodeid nidParent2) throws HgRuntimeException;
427 } 438 }
428 439
429 protected HgParentChildMap<? extends Revlog> getParentWalker() { 440 protected HgParentChildMap<? extends Revlog> getParentWalker() throws HgRuntimeException {
430 HgParentChildMap<Revlog> pw = new HgParentChildMap<Revlog>(this); 441 HgParentChildMap<Revlog> pw = new HgParentChildMap<Revlog>(this);
431 pw.init(); 442 pw.init();
432 return pw; 443 return pw;
433 } 444 }
434 445