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 }