comparison src/org/tmatesoft/hg/repo/Revlog.java @ 354:5f9073eabf06

Propagate errors with exceptions up to a end client
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 01 Dec 2011 05:21:40 +0100
parents 8da7ade36c57
children f2c11fe7f3e9
comparison
equal deleted inserted replaced
353:0f3687e79f5a 354:5f9073eabf06
28 import java.util.LinkedList; 28 import java.util.LinkedList;
29 import java.util.List; 29 import java.util.List;
30 30
31 import org.tmatesoft.hg.core.HgBadStateException; 31 import org.tmatesoft.hg.core.HgBadStateException;
32 import org.tmatesoft.hg.core.HgException; 32 import org.tmatesoft.hg.core.HgException;
33 import org.tmatesoft.hg.core.HgInvalidControlFileException;
33 import org.tmatesoft.hg.core.HgInvalidRevisionException; 34 import org.tmatesoft.hg.core.HgInvalidRevisionException;
34 import org.tmatesoft.hg.core.Nodeid; 35 import org.tmatesoft.hg.core.Nodeid;
35 import org.tmatesoft.hg.internal.ArrayHelper; 36 import org.tmatesoft.hg.internal.ArrayHelper;
36 import org.tmatesoft.hg.internal.DataAccess; 37 import org.tmatesoft.hg.internal.DataAccess;
37 import org.tmatesoft.hg.internal.Experimental; 38 import org.tmatesoft.hg.internal.Experimental;
84 } 85 }
85 86
86 public final int getLastRevision() { 87 public final int getLastRevision() {
87 return content.revisionCount() - 1; 88 return content.revisionCount() - 1;
88 } 89 }
89 90
90 public final Nodeid getRevision(int revision) throws HgInvalidRevisionException { 91 /**
92 * Map revision index to unique revision identifier (nodeid)
93 *
94 * @param revision index of the entry in this revlog
95 * @return revision nodeid of the entry
96 *
97 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
98 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
99 */
100 public final Nodeid getRevision(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException {
91 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it 101 // XXX cache nodeids? Rather, if context.getCache(this).getRevisionMap(create == false) != null, use it
92 return Nodeid.fromBinary(content.nodeid(revision), 0); 102 return Nodeid.fromBinary(content.nodeid(revision), 0);
93 } 103 }
94 104
95 /** 105 /**
121 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link RevisionMap} may come handy. 131 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link RevisionMap} may come handy.
122 * 132 *
123 * @param nid revision to look up 133 * @param nid revision to look up
124 * @return revision local index in this revlog 134 * @return revision local index in this revlog
125 * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog 135 * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog
126 */ 136 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
127 public final int getLocalRevision(Nodeid nid) throws HgInvalidRevisionException { 137 */
138 public final int getLocalRevision(Nodeid nid) throws HgInvalidControlFileException, HgInvalidRevisionException {
128 int revision = content.findLocalRevisionNumber(nid); 139 int revision = content.findLocalRevisionNumber(nid);
129 if (revision == BAD_REVISION) { 140 if (revision == BAD_REVISION) {
130 throw new HgInvalidRevisionException(String.format("Bad revision of %s", this /*XXX HgDataFile.getPath might be more suitable here*/), nid, null); 141 throw new HgInvalidRevisionException(String.format("Bad revision of %s", this /*XXX HgDataFile.getPath might be more suitable here*/), nid, null);
131 } 142 }
132 return revision; 143 return revision;
133 } 144 }
134 145
135 // Till now, i follow approach that NULL nodeid is never part of revlog 146 /**
136 public final boolean isKnown(Nodeid nodeid) { 147 * Note, {@link Nodeid#NULL} nodeid is not reported as known in any revlog.
148 *
149 * @param nodeid
150 * @return
151 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
152 */
153 public final boolean isKnown(Nodeid nodeid) throws HgInvalidControlFileException {
137 final int rn = content.findLocalRevisionNumber(nodeid); 154 final int rn = content.findLocalRevisionNumber(nodeid);
138 if (BAD_REVISION == rn) { 155 if (BAD_REVISION == rn) {
139 return false; 156 return false;
140 } 157 }
141 if (rn < 0 || rn >= content.revisionCount()) { 158 if (rn < 0 || rn >= content.revisionCount()) {
142 // Sanity check 159 // Sanity check
143 throw new IllegalStateException(); 160 throw new HgBadStateException(String.format("Revision index %d found for nodeid %s is not from the range [0..%d]", rn, nodeid.shortNotation(), content.revisionCount()-1));
144 } 161 }
145 return true; 162 return true;
146 } 163 }
147 164
148 /** 165 /**
153 rawContent(getLocalRevision(nodeid), sink); 170 rawContent(getLocalRevision(nodeid), sink);
154 } 171 }
155 172
156 /** 173 /**
157 * @param revision - repo-local index of this file change (not a changelog revision number!) 174 * @param revision - repo-local index of this file change (not a changelog revision number!)
175 * FIXME is it necessary to have IOException along with HgException here?
158 */ 176 */
159 protected void rawContent(int revision, ByteChannel sink) throws HgException, IOException, CancelledException, HgInvalidRevisionException { 177 protected void rawContent(int revision, ByteChannel sink) throws HgException, IOException, CancelledException, HgInvalidRevisionException {
160 if (sink == null) { 178 if (sink == null) {
161 throw new IllegalArgumentException(); 179 throw new IllegalArgumentException();
162 } 180 }