Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 367:2fadf8695f8a
Use 'revision index' instead of the vague 'local revision number' concept in the API
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 16 Dec 2011 15:37:27 +0100 |
parents | 189dc6dc1c3e |
children | 8107b95f4280 |
comparison
equal
deleted
inserted
replaced
366:189dc6dc1c3e | 367:2fadf8695f8a |
---|---|
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.repo; | 17 package org.tmatesoft.hg.repo; |
18 | 18 |
19 import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision; | 19 import static org.tmatesoft.hg.repo.HgInternals.wrongRevisionIndex; |
20 import static org.tmatesoft.hg.repo.HgRepository.*; | 20 import static org.tmatesoft.hg.repo.HgRepository.*; |
21 | 21 |
22 import java.io.ByteArrayOutputStream; | 22 import java.io.ByteArrayOutputStream; |
23 import java.io.File; | 23 import java.io.File; |
24 import java.io.FileInputStream; | 24 import java.io.FileInputStream; |
85 public Path getPath() { | 85 public Path getPath() { |
86 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names? | 86 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names? |
87 } | 87 } |
88 | 88 |
89 /** | 89 /** |
90 * Handy shorthand for {@link #length(int) length(getLocalRevision(nodeid))} | 90 * Handy shorthand for {@link #length(int) length(getRevisionIndex(nodeid))} |
91 * | 91 * |
92 * @param nodeid revision of the file | 92 * @param nodeid revision of the file |
93 * | 93 * |
94 * @return size of the file content at the given revision | 94 * @return size of the file content at the given revision |
95 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog | 95 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog |
96 * @throws HgDataStreamException if attempt to access file metadata failed | 96 * @throws HgDataStreamException if attempt to access file metadata failed |
97 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 97 * @throws HgInvalidControlFileException if access to revlog index/data entry failed |
98 */ | 98 */ |
99 public int length(Nodeid nodeid) throws HgDataStreamException, HgInvalidControlFileException, HgInvalidRevisionException { | 99 public int length(Nodeid nodeid) throws HgDataStreamException, HgInvalidControlFileException, HgInvalidRevisionException { |
100 return length(getLocalRevision(nodeid)); | 100 return length(getRevisionIndex(nodeid)); |
101 } | 101 } |
102 | 102 |
103 /** | 103 /** |
104 * @param fileRevisionIndex local revision index, non-negative. From predefined constants, only {@link HgRepository#TIP} makes sense. | |
104 * @return size of the file content at the revision identified by local revision number. | 105 * @return size of the file content at the revision identified by local revision number. |
105 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog | 106 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog |
106 * @throws HgDataStreamException if attempt to access file metadata failed | 107 * @throws HgDataStreamException if attempt to access file metadata failed |
107 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 108 * @throws HgInvalidControlFileException if access to revlog index/data entry failed |
108 */ | 109 */ |
109 public int length(int localRev) throws HgDataStreamException, HgInvalidControlFileException, HgInvalidRevisionException { | 110 public int length(int fileRevisionIndex) throws HgDataStreamException, HgInvalidControlFileException, HgInvalidRevisionException { |
110 if (metadata == null || !metadata.checked(localRev)) { | 111 // TODO support WORKING_COPY constant |
111 checkAndRecordMetadata(localRev); | 112 if (metadata == null || !metadata.checked(fileRevisionIndex)) { |
112 } | 113 checkAndRecordMetadata(fileRevisionIndex); |
113 final int dataLen = content.dataLength(localRev); | 114 } |
114 if (metadata.known(localRev)) { | 115 final int dataLen = content.dataLength(fileRevisionIndex); |
115 return dataLen - metadata.dataOffset(localRev); | 116 if (metadata.known(fileRevisionIndex)) { |
117 return dataLen - metadata.dataOffset(fileRevisionIndex); | |
116 } | 118 } |
117 return dataLen; | 119 return dataLen; |
118 } | 120 } |
119 | 121 |
120 /** | 122 /** |
196 } else { | 198 } else { |
197 content(revision, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath()))); | 199 content(revision, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath()))); |
198 } | 200 } |
199 } | 201 } |
200 | 202 |
201 // for data files need to check heading of the file content for possible metadata | 203 /** |
202 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8- | 204 * |
203 public void content(int revision, ByteChannel sink) throws HgDataStreamException, HgInvalidControlFileException, CancelledException, HgInvalidRevisionException { | 205 * @param fileRevisionIndex local revision index, non-negative. From predefined constants, {@link HgRepository#TIP} and {@link HgRepository#WORKING_COPY} make sense. |
204 if (revision == TIP) { | 206 * @param sink |
205 revision = getLastRevision(); | 207 * @throws HgDataStreamException FIXME |
206 } | 208 * @throws HgInvalidControlFileException |
207 if (revision == WORKING_COPY) { | 209 * @throws CancelledException |
210 * @throws HgInvalidRevisionException | |
211 */ | |
212 public void content(int fileRevisionIndex, ByteChannel sink) throws HgDataStreamException, HgInvalidControlFileException, CancelledException, HgInvalidRevisionException { | |
213 // for data files need to check heading of the file content for possible metadata | |
214 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8- | |
215 if (fileRevisionIndex == TIP) { | |
216 fileRevisionIndex = getLastRevision(); | |
217 } | |
218 if (fileRevisionIndex == WORKING_COPY) { | |
208 // sink is supposed to come into workingCopy without filters | 219 // sink is supposed to come into workingCopy without filters |
209 // thus we shall not get here (into #content) from #contentWithFilters(WC) | 220 // thus we shall not get here (into #content) from #contentWithFilters(WC) |
210 workingCopy(sink); | 221 workingCopy(sink); |
211 return; | 222 return; |
212 } | 223 } |
213 if (wrongLocalRevision(revision) || revision == BAD_REVISION) { | 224 if (wrongRevisionIndex(fileRevisionIndex) || fileRevisionIndex == BAD_REVISION) { |
214 throw new HgInvalidRevisionException(revision); | 225 throw new HgInvalidRevisionException(fileRevisionIndex); |
215 } | 226 } |
216 if (sink == null) { | 227 if (sink == null) { |
217 throw new IllegalArgumentException(); | 228 throw new IllegalArgumentException(); |
218 } | 229 } |
219 if (metadata == null) { | 230 if (metadata == null) { |
220 metadata = new Metadata(); | 231 metadata = new Metadata(); |
221 } | 232 } |
222 ErrorHandlingInspector insp; | 233 ErrorHandlingInspector insp; |
223 if (metadata.none(revision)) { | 234 if (metadata.none(fileRevisionIndex)) { |
224 insp = new ContentPipe(sink, 0, getRepo().getContext().getLog()); | 235 insp = new ContentPipe(sink, 0, getRepo().getContext().getLog()); |
225 } else if (metadata.known(revision)) { | 236 } else if (metadata.known(fileRevisionIndex)) { |
226 insp = new ContentPipe(sink, metadata.dataOffset(revision), getRepo().getContext().getLog()); | 237 insp = new ContentPipe(sink, metadata.dataOffset(fileRevisionIndex), getRepo().getContext().getLog()); |
227 } else { | 238 } else { |
228 // do not know if there's metadata | 239 // do not know if there's metadata |
229 insp = new MetadataInspector(metadata, getPath(), new ContentPipe(sink, 0, getRepo().getContext().getLog())); | 240 insp = new MetadataInspector(metadata, getPath(), new ContentPipe(sink, 0, getRepo().getContext().getLog())); |
230 } | 241 } |
231 insp.checkCancelled(); | 242 insp.checkCancelled(); |
232 super.content.iterate(revision, revision, true, insp); | 243 super.content.iterate(fileRevisionIndex, fileRevisionIndex, true, insp); |
233 try { | 244 try { |
234 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe? | 245 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe? |
235 } catch (HgDataStreamException ex) { | 246 } catch (HgDataStreamException ex) { |
236 throw ex; | 247 throw ex; |
237 } catch (IOException ex) { | 248 } catch (IOException ex) { |
238 throw new HgDataStreamException(getPath(), ex).setRevisionNumber(revision); | 249 throw new HgDataStreamException(getPath(), ex).setRevisionIndex(fileRevisionIndex); |
239 } catch (HgException ex) { | 250 } catch (HgException ex) { |
240 // shall not happen, unless we changed ContentPipe or its subclass | 251 // shall not happen, unless we changed ContentPipe or its subclass |
241 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex); | 252 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex); |
242 } | 253 } |
243 } | 254 } |
398 } | 409 } |
399 changelog.rangeInternal(inspector, commitRevisions); | 410 changelog.rangeInternal(inspector, commitRevisions); |
400 } | 411 } |
401 | 412 |
402 /** | 413 /** |
403 * For a given local revision of the file, find out local revision in the changelog. | 414 * For a given revision of the file (identified with revision index), find out index of the corresponding changeset. |
404 * FIXME rename to getChangesetRevisionIndex() | |
405 * | 415 * |
406 * @return changeset revision index | 416 * @return changeset revision index |
407 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog | 417 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog |
408 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 418 * @throws HgInvalidControlFileException if access to revlog index/data entry failed |
409 */ | 419 */ |
420 public int getChangesetRevisionIndex(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException { | |
421 return content.linkRevision(revision); | |
422 } | |
423 /** | |
424 * @deprecated use {@link #getChangesetRevisionIndex(int)} instead | |
425 */ | |
426 @Deprecated | |
410 public int getChangesetLocalRevision(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException { | 427 public int getChangesetLocalRevision(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException { |
411 return content.linkRevision(revision); | 428 return getChangesetRevisionIndex(revision); |
412 } | 429 } |
413 | 430 |
414 /** | 431 /** |
415 * Complements {@link #getChangesetLocalRevision(int)} to get changeset revision that corresponds to supplied file revision | 432 * Complements {@link #getChangesetRevisionIndex(int)} to get changeset revision that corresponds to supplied file revision |
416 * | 433 * |
417 * @param nid revision of the file | 434 * @param nid revision of the file |
418 * @return changeset revision | 435 * @return changeset revision |
419 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog | 436 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog |
420 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 437 * @throws HgInvalidControlFileException if access to revlog index/data entry failed |
421 */ | 438 */ |
422 public Nodeid getChangesetRevision(Nodeid nid) throws HgInvalidControlFileException, HgInvalidRevisionException { | 439 public Nodeid getChangesetRevision(Nodeid nid) throws HgInvalidControlFileException, HgInvalidRevisionException { |
423 int changelogRevision = getChangesetLocalRevision(getLocalRevision(nid)); | 440 int changelogRevision = getChangesetRevisionIndex(getRevisionIndex(nid)); |
424 return getRepo().getChangelog().getRevision(changelogRevision); | 441 return getRepo().getChangelog().getRevision(changelogRevision); |
425 } | 442 } |
426 | 443 |
427 /** | 444 /** |
428 * | 445 * |
603 delegate.next(revisionNumber, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data); | 620 delegate.next(revisionNumber, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data); |
604 } | 621 } |
605 } catch (IOException ex) { | 622 } catch (IOException ex) { |
606 recordFailure(ex); | 623 recordFailure(ex); |
607 } catch (HgDataStreamException ex) { | 624 } catch (HgDataStreamException ex) { |
608 recordFailure(ex.setRevisionNumber(revisionNumber)); | 625 recordFailure(ex.setRevisionIndex(revisionNumber)); |
609 } | 626 } |
610 } | 627 } |
611 | 628 |
612 private int parseMetadata(DataAccess data, final int daLength, ArrayList<MetadataEntry> _metadata) throws IOException, HgDataStreamException { | 629 private int parseMetadata(DataAccess data, final int daLength, ArrayList<MetadataEntry> _metadata) throws IOException, HgDataStreamException { |
613 int lastEntryStart = 2; | 630 int lastEntryStart = 2; |