Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/RevlogStream.java @ 423:9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 23 Mar 2012 22:51:18 +0100 |
parents | 6c22bdc0bdfd |
children | 48f993aa2f41 |
comparison
equal
deleted
inserted
replaced
422:5d1cc7366d04 | 423:9c9c442b5f2e |
---|---|
21 | 21 |
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; | |
27 import org.tmatesoft.hg.core.HgException; | |
28 import org.tmatesoft.hg.core.HgInvalidControlFileException; | |
29 import org.tmatesoft.hg.core.HgInvalidRevisionException; | |
30 import org.tmatesoft.hg.core.Nodeid; | 26 import org.tmatesoft.hg.core.Nodeid; |
31 import org.tmatesoft.hg.repo.HgInternals; | 27 import org.tmatesoft.hg.repo.HgInternals; |
28 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | |
29 import org.tmatesoft.hg.repo.HgInvalidRevisionException; | |
30 import org.tmatesoft.hg.repo.HgInvalidStateException; | |
32 import org.tmatesoft.hg.repo.HgRepository; | 31 import org.tmatesoft.hg.repo.HgRepository; |
33 | 32 |
34 | 33 |
35 /** | 34 /** |
36 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations), | 35 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations), |
204 | 203 |
205 private final int REVLOGV1_RECORD_SIZE = 64; | 204 private final int REVLOGV1_RECORD_SIZE = 64; |
206 | 205 |
207 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg | 206 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg |
208 // ? boolean needsNodeid | 207 // ? boolean needsNodeid |
209 public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ { | 208 public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException { |
210 initOutline(); | 209 initOutline(); |
211 final int indexSize = revisionCount(); | 210 final int indexSize = revisionCount(); |
212 if (indexSize == 0) { | 211 if (indexSize == 0) { |
213 return; | 212 return; |
214 } | 213 } |
227 r.range(start, end); | 226 r.range(start, end); |
228 } catch (IOException ex) { | 227 } catch (IOException ex) { |
229 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); | 228 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); |
230 } catch (HgInvalidControlFileException ex) { | 229 } catch (HgInvalidControlFileException ex) { |
231 throw ex; | 230 throw ex; |
232 } catch (HgException ex) { | |
233 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); | |
234 } finally { | 231 } finally { |
235 r.finish(); | 232 r.finish(); |
236 } | 233 } |
237 } | 234 } |
238 | 235 |
275 } | 272 } |
276 } catch (IOException ex) { | 273 } catch (IOException ex) { |
277 final int c = sortedRevisions.length; | 274 final int c = sortedRevisions.length; |
278 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); | 275 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); |
279 } catch (HgInvalidControlFileException ex) { | 276 } catch (HgInvalidControlFileException ex) { |
277 // TODO post-1.0 fill HgRuntimeException with appropriate file (either index or data, depending on error source) | |
280 throw ex; | 278 throw ex; |
281 } catch (HgException ex) { | |
282 final int c = sortedRevisions.length; | |
283 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); | |
284 } finally { | 279 } finally { |
285 r.finish(); | 280 r.finish(); |
286 } | 281 } |
287 } | 282 } |
288 | 283 |
349 if (inline) { | 344 if (inline) { |
350 int o = Internals.ltoi(offset); | 345 int o = Internals.ltoi(offset); |
351 if (o != offset) { | 346 if (o != offset) { |
352 // just in case, can't happen, ever, unless HG (or some other bad tool) produces index file | 347 // just in case, can't happen, ever, unless HG (or some other bad tool) produces index file |
353 // with inlined data of size greater than 2 Gb. | 348 // with inlined data of size greater than 2 Gb. |
354 throw new HgBadStateException("Data too big, offset didn't fit to sizeof(int)"); | 349 throw new HgInvalidStateException("Data too big, offset didn't fit to sizeof(int)"); |
355 } | 350 } |
356 resOffsets.add(o + REVLOGV1_RECORD_SIZE * resOffsets.size()); | 351 resOffsets.add(o + REVLOGV1_RECORD_SIZE * resOffsets.size()); |
357 da.skip(3*4 + 32 + compressedLen); // Check: 44 (skip) + 20 (read) = 64 (total RevlogNG record size) | 352 da.skip(3*4 + 32 + compressedLen); // Check: 44 (skip) + 20 (read) = 64 (total RevlogNG record size) |
358 } else { | 353 } else { |
359 da.skip(3*4 + 32); | 354 da.skip(3*4 + 32); |
370 long l = da.readLong(); | 365 long l = da.readLong(); |
371 offset = l >>> 16; | 366 offset = l >>> 16; |
372 } | 367 } |
373 } | 368 } |
374 } catch (IOException ex) { | 369 } catch (IOException ex) { |
375 ex.printStackTrace(); // FIXME, log error is not enough | 370 throw new HgInvalidControlFileException("Failed to analyze revlog index", ex, indexFile); |
376 // too bad, no outline then, but don't fail with NPE | |
377 baseRevisions = new int[0]; | |
378 } finally { | 371 } finally { |
379 da.done(); | 372 da.done(); |
380 } | 373 } |
381 } | 374 } |
382 | 375 |
426 daData.done(); | 419 daData.done(); |
427 } | 420 } |
428 // System.out.printf("applyTime:%d ms, inspectorTime: %d ms\n", applyTime, inspectorTime); // TIMING | 421 // System.out.printf("applyTime:%d ms, inspectorTime: %d ms\n", applyTime, inspectorTime); // TIMING |
429 } | 422 } |
430 | 423 |
431 public boolean range(int start, int end) throws IOException, HgException { | 424 public boolean range(int start, int end) throws IOException { |
432 byte[] nodeidBuf = new byte[20]; | 425 byte[] nodeidBuf = new byte[20]; |
433 int i; | 426 int i; |
434 // it (i.e. replace with i >= start) | 427 // it (i.e. replace with i >= start) |
435 if (needData && (i = getBaseRevision(start)) < start) { | 428 if (needData && (i = getBaseRevision(start)) < start) { |
436 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData | 429 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData |
563 | 556 |
564 public interface Inspector { | 557 public interface Inspector { |
565 // XXX boolean retVal to indicate whether to continue? | 558 // XXX boolean retVal to indicate whether to continue? |
566 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) | 559 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) |
567 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment | 560 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment |
568 void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data) throws HgException; | 561 void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data); |
569 } | 562 } |
570 } | 563 } |