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