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 } |
