Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/RevlogStream.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 | 5f9073eabf06 |
children | 2fadf8695f8a |
comparison
equal
deleted
inserted
replaced
365:3572fcb06473 | 366:189dc6dc1c3e |
---|---|
22 import java.io.File; | 22 import java.io.File; |
23 import java.io.IOException; | 23 import java.io.IOException; |
24 import java.util.zip.Inflater; | 24 import java.util.zip.Inflater; |
25 | 25 |
26 import org.tmatesoft.hg.core.HgBadStateException; | 26 import org.tmatesoft.hg.core.HgBadStateException; |
27 import org.tmatesoft.hg.core.HgException; | |
27 import org.tmatesoft.hg.core.HgInvalidControlFileException; | 28 import org.tmatesoft.hg.core.HgInvalidControlFileException; |
28 import org.tmatesoft.hg.core.HgInvalidRevisionException; | 29 import org.tmatesoft.hg.core.HgInvalidRevisionException; |
29 import org.tmatesoft.hg.core.Nodeid; | 30 import org.tmatesoft.hg.core.Nodeid; |
30 import org.tmatesoft.hg.repo.HgInternals; | 31 import org.tmatesoft.hg.repo.HgInternals; |
31 import org.tmatesoft.hg.repo.HgRepository; | 32 import org.tmatesoft.hg.repo.HgRepository; |
179 | 180 |
180 private final int REVLOGV1_RECORD_SIZE = 64; | 181 private final int REVLOGV1_RECORD_SIZE = 64; |
181 | 182 |
182 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg | 183 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg |
183 // ? boolean needsNodeid | 184 // ? boolean needsNodeid |
184 public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException { | 185 public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ { |
185 initOutline(); | 186 initOutline(); |
186 final int indexSize = revisionCount(); | 187 final int indexSize = revisionCount(); |
187 if (indexSize == 0) { | 188 if (indexSize == 0) { |
188 return; | 189 return; |
189 } | 190 } |
199 ReaderN1 r = new ReaderN1(needData, inspector); | 200 ReaderN1 r = new ReaderN1(needData, inspector); |
200 try { | 201 try { |
201 r.start(end - start + 1); | 202 r.start(end - start + 1); |
202 r.range(start, end); | 203 r.range(start, end); |
203 } catch (IOException ex) { | 204 } catch (IOException ex) { |
204 throw new HgBadStateException(ex); // FIXME need better handling | 205 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); |
206 } catch (HgInvalidControlFileException ex) { | |
207 throw ex; | |
208 } catch (HgException ex) { | |
209 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); | |
205 } finally { | 210 } finally { |
206 r.finish(); | 211 r.finish(); |
207 } | 212 } |
208 } | 213 } |
209 | 214 |
212 * revisions are of interest. | 217 * revisions are of interest. |
213 * @param sortedRevisions revisions to walk, in ascending order. | 218 * @param sortedRevisions revisions to walk, in ascending order. |
214 * @param needData whether inspector needs access to header only | 219 * @param needData whether inspector needs access to header only |
215 * @param inspector callback to process entries | 220 * @param inspector callback to process entries |
216 */ | 221 */ |
217 public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgInvalidRevisionException { | 222 public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ { |
218 final int indexSize = revisionCount(); | 223 final int indexSize = revisionCount(); |
219 if (indexSize == 0 || sortedRevisions.length == 0) { | 224 if (indexSize == 0 || sortedRevisions.length == 0) { |
220 return; | 225 return; |
221 } | 226 } |
222 if (sortedRevisions[0] > indexSize) { | 227 if (sortedRevisions[0] > indexSize) { |
243 if (!r.range(sortedRevisions[x], sortedRevisions[i-1])) { | 248 if (!r.range(sortedRevisions[x], sortedRevisions[i-1])) { |
244 return; | 249 return; |
245 } | 250 } |
246 } | 251 } |
247 } catch (IOException ex) { | 252 } catch (IOException ex) { |
248 throw new HgBadStateException(ex); // FIXME need better handling | 253 final int c = sortedRevisions.length; |
254 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); | |
255 } catch (HgInvalidControlFileException ex) { | |
256 throw ex; | |
257 } catch (HgException ex) { | |
258 final int c = sortedRevisions.length; | |
259 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); | |
249 } finally { | 260 } finally { |
250 r.finish(); | 261 r.finish(); |
251 } | 262 } |
252 } | 263 } |
253 | 264 |
335 long l = da.readLong(); | 346 long l = da.readLong(); |
336 offset = l >>> 16; | 347 offset = l >>> 16; |
337 } | 348 } |
338 } | 349 } |
339 } catch (IOException ex) { | 350 } catch (IOException ex) { |
340 ex.printStackTrace(); // log error | 351 ex.printStackTrace(); // FIXME, log error is not enough |
341 // too bad, no outline then, but don't fail with NPE | 352 // too bad, no outline then, but don't fail with NPE |
342 baseRevisions = new int[0]; | 353 baseRevisions = new int[0]; |
343 } finally { | 354 } finally { |
344 da.done(); | 355 da.done(); |
345 } | 356 } |
346 } | 357 } |
347 | 358 |
348 /** | 359 /** |
349 * operation with single file open/close and multiple diverse reads. | 360 * operation with single file open/close and multiple diverse reads. |
350 * XXX initOutline might need similar extraction to keen N1 format knowledge | 361 * XXX initOutline might need similar extraction to keep N1 format knowledge |
351 */ | 362 */ |
352 class ReaderN1 { | 363 class ReaderN1 { |
353 private final Inspector inspector; | 364 private final Inspector inspector; |
354 private final boolean needData; | 365 private final boolean needData; |
355 private DataAccess daIndex = null, daData = null; | 366 private DataAccess daIndex = null, daData = null; |
391 daData.done(); | 402 daData.done(); |
392 } | 403 } |
393 // System.out.printf("applyTime:%d ms, inspectorTime: %d ms\n", applyTime, inspectorTime); // TIMING | 404 // System.out.printf("applyTime:%d ms, inspectorTime: %d ms\n", applyTime, inspectorTime); // TIMING |
394 } | 405 } |
395 | 406 |
396 public boolean range(int start, int end) throws IOException { | 407 public boolean range(int start, int end) throws IOException, HgException { |
397 byte[] nodeidBuf = new byte[20]; | 408 byte[] nodeidBuf = new byte[20]; |
398 int i; | 409 int i; |
399 // it (i.e. replace with i >= start) | 410 // it (i.e. replace with i >= start) |
400 if (needData && (i = getBaseRevision(start)) < start) { | 411 if (needData && (i = getBaseRevision(start)) < start) { |
401 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData | 412 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData |
515 | 526 |
516 public interface Inspector { | 527 public interface Inspector { |
517 // XXX boolean retVal to indicate whether to continue? | 528 // XXX boolean retVal to indicate whether to continue? |
518 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) | 529 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) |
519 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment | 530 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment |
520 void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data); | 531 void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data) throws HgException; |
521 } | 532 } |
522 } | 533 } |