comparison src/org/tmatesoft/hg/repo/Revlog.java @ 366:189dc6dc1c3e

Use exceptions to expose errors reading mercurial data
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 16 Dec 2011 04:43:18 +0100
parents 91d75e1bac9f
children 2fadf8695f8a
comparison
equal deleted inserted replaced
365:3572fcb06473 366:189dc6dc1c3e
97 * @return revision nodeid of the entry 97 * @return revision nodeid of the entry
98 * 98 *
99 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog 99 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
100 * @throws HgInvalidControlFileException if access to revlog index/data entry failed 100 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
101 */ 101 */
102 public final Nodeid getRevision(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException { 102 public final Nodeid getRevision(int revision) throws HgInvalidRevisionException, HgInvalidControlFileException {
103 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it 103 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it
104 return Nodeid.fromBinary(content.nodeid(revision), 0); 104 return Nodeid.fromBinary(content.nodeid(revision), 0);
105 } 105 }
106 106
107 /** 107 /**
108 * FIXME need to be careful about (1) ordering of the revisions in the return list; (2) modifications (sorting) of the argument array 108 * FIXME need to be careful about (1) ordering of the revisions in the return list; (2) modifications (sorting) of the argument array
109 */ 109 */
110 public final List<Nodeid> getRevisions(int... revisions) throws HgInvalidRevisionException { 110 public final List<Nodeid> getRevisions(int... revisions) throws HgInvalidRevisionException, HgInvalidControlFileException {
111 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(revisions.length); 111 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(revisions.length);
112 Arrays.sort(revisions); 112 Arrays.sort(revisions);
113 getRevisionsInternal(rv, revisions); 113 getRevisionsInternal(rv, revisions);
114 return rv; 114 return rv;
115 } 115 }
116 116
117 /*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgInvalidRevisionException { 117 /*package-local*/ void getRevisionsInternal(final List<Nodeid> retVal, int[] sortedRevs) throws HgInvalidRevisionException, HgInvalidControlFileException {
118 // once I have getRevisionMap and may find out whether it is avalable from cache, 118 // once I have getRevisionMap and may find out whether it is avalable from cache,
119 // may use it, perhaps only for small number of revisions 119 // may use it, perhaps only for small number of revisions
120 content.iterate(sortedRevs, false, new RevlogStream.Inspector() { 120 content.iterate(sortedRevs, false, new RevlogStream.Inspector() {
121 121
122 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { 122 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
194 * @param parent1 - byte[20] or null, if parent's nodeid is not needed 194 * @param parent1 - byte[20] or null, if parent's nodeid is not needed
195 * @param parent2 - byte[20] or null, if second parent's nodeid is not needed 195 * @param parent2 - byte[20] or null, if second parent's nodeid is not needed
196 * @throws HgInvalidRevisionException 196 * @throws HgInvalidRevisionException
197 * @throws IllegalArgumentException 197 * @throws IllegalArgumentException
198 */ 198 */
199 public void parents(int revision, int[] parentRevisions, byte[] parent1, byte[] parent2) throws HgInvalidRevisionException { 199 public void parents(int revision, int[] parentRevisions, byte[] parent1, byte[] parent2) throws HgInvalidRevisionException, HgInvalidControlFileException {
200 if (revision != TIP && !(revision >= 0 && revision < content.revisionCount())) { 200 if (revision != TIP && !(revision >= 0 && revision < content.revisionCount())) {
201 throw new HgInvalidRevisionException(revision); 201 throw new HgInvalidRevisionException(revision);
202 } 202 }
203 if (parentRevisions == null || parentRevisions.length < 2) { 203 if (parentRevisions == null || parentRevisions.length < 2) {
204 throw new IllegalArgumentException(String.valueOf(parentRevisions)); 204 throw new IllegalArgumentException(String.valueOf(parentRevisions));
243 } 243 }
244 } 244 }
245 } 245 }
246 246
247 @Experimental 247 @Experimental
248 public void walk(int start, int end, final Revlog.Inspector inspector) throws HgInvalidRevisionException { 248 public void walk(int start, int end, final Revlog.Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
249 int lastRev = getLastRevision(); 249 int lastRev = getLastRevision();
250 if (start == TIP) { 250 if (start == TIP) {
251 start = lastRev; 251 start = lastRev;
252 } 252 }
253 if (end == TIP) { 253 if (end == TIP) {
330 if (parent2Revision != -1) { // revlog of DataAccess.java has p2 set when p1 is -1 330 if (parent2Revision != -1) { // revlog of DataAccess.java has p2 set when p1 is -1
331 secondParent[ix] = sequential[parent2Revision]; 331 secondParent[ix] = sequential[parent2Revision];
332 } 332 }
333 } 333 }
334 334
335 public void init() { 335 public void init() throws HgInvalidControlFileException {
336 final int revisionCount = Revlog.this.getRevisionCount(); 336 final int revisionCount = Revlog.this.getRevisionCount();
337 firstParent = new Nodeid[revisionCount]; 337 firstParent = new Nodeid[revisionCount];
338 // although branches/merges are less frequent, and most of secondParent would be -1/null, some sort of 338 // although branches/merges are less frequent, and most of secondParent would be -1/null, some sort of
339 // SparseOrderedList might be handy, provided its inner structures do not overweight simplicity of an array 339 // SparseOrderedList might be handy, provided its inner structures do not overweight simplicity of an array
340 // FIXME IntMap is right candidate? 340 // FIXME IntMap is right candidate?
517 } 517 }
518 518
519 /** 519 /**
520 * @return <code>this</code> for convenience. 520 * @return <code>this</code> for convenience.
521 */ 521 */
522 public RevisionMap init(/*XXX Pool<Nodeid> to reuse nodeids, if possible. */) { 522 public RevisionMap init(/*XXX Pool<Nodeid> to reuse nodeids, if possible. */) throws HgInvalidControlFileException{
523 // XXX HgRepository.register((RepoChangeListener) this); // listen to changes in repo, re-init if needed? 523 // XXX HgRepository.register((RepoChangeListener) this); // listen to changes in repo, re-init if needed?
524 final int revisionCount = Revlog.this.getRevisionCount(); 524 final int revisionCount = Revlog.this.getRevisionCount();
525 sequential = new Nodeid[revisionCount]; 525 sequential = new Nodeid[revisionCount];
526 sorted = new Nodeid[revisionCount]; 526 sorted = new Nodeid[revisionCount];
527 Revlog.this.walk(0, TIP, this); 527 Revlog.this.walk(0, TIP, this);