Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/RevlogStream.java @ 398:c76c57f6b961
Merge fixed for issue 24 and issue 26 from smartgit3 branch
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Thu, 23 Feb 2012 21:53:21 +0100 | 
| parents | 0ae53c32ecef 5e95b0da26f2 | 
| children | 6c22bdc0bdfd | 
   comparison
  equal
  deleted
  inserted
  replaced
| 396:0ae53c32ecef | 398:c76c57f6b961 | 
|---|---|
| 486 streamOffset = (int) offset; | 486 streamOffset = (int) offset; | 
| 487 streamDataAccess = daData; | 487 streamDataAccess = daData; | 
| 488 daData.seek(streamOffset); | 488 daData.seek(streamOffset); | 
| 489 } | 489 } | 
| 490 final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch | 490 final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch | 
| 491 if (streamDataAccess.isEmpty()) { | 491 if (streamDataAccess.isEmpty() || compressedLen == 0) { | 
| 492 userDataAccess = new DataAccess(); // empty | 492 userDataAccess = new DataAccess(); // empty | 
| 493 } else { | 493 } else { | 
| 494 final byte firstByte = streamDataAccess.readByte(); | 494 final byte firstByte = streamDataAccess.readByte(); | 
| 495 if (firstByte == 0x78 /* 'x' */) { | 495 if (firstByte == 0x78 /* 'x' */) { | 
| 496 inflater.reset(); | 496 inflater.reset(); | 
| 497 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, patchToPrevious ? -1 : actualLen, inflater, inflaterBuffer); | 497 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, patchToPrevious ? -1 : actualLen, inflater, inflaterBuffer); | 
| 498 } else if (firstByte == 0x75 /* 'u' */) { | 498 } else if (firstByte == 0x75 /* 'u' */) { | 
| 499 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1); | 499 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1); | 
| 500 } else { | 500 } else { | 
| 501 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0' | 501 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0' but I don't see reason not to return data as is | 
| 502 // but I don't see reason not to return data as is | 502 // | 
| 503 // although firstByte is already read from the streamDataAccess, FilterDataAccess#readByte would seek to | |
| 504 // initial offset before first attempt to read a byte | |
| 503 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen); | 505 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen); | 
| 504 } | 506 } | 
| 505 } | 507 } | 
| 506 // XXX | 508 // userDataAccess is revision content, either complete revision, patch of a previous content, or an empty patch | 
| 507 if (patchToPrevious && !userDataAccess.isEmpty() /* Issue 22, empty patch to an empty base revision*/) { | 509 if (patchToPrevious) { | 
| 508 // this is a patch | 510 // this is a patch | 
| 509 patch.read(userDataAccess); | 511 if (userDataAccess.isEmpty()) { | 
| 510 userDataAccess.done(); | 512 // Issue 22, empty patch to an empty base revision | 
| 511 // | 513 // Issue 24, empty patch to non-empty base revision | 
| 512 // it shall be reset at the end of prev iteration, when it got assigned from userDataAccess | 514 // empty patch modifies nothing, use content of a previous revision (shall present - it's a patch here) | 
| 513 // however, actual userDataAccess and lastUserData may share Inflater object, which needs to be reset | 515 // | 
| 514 // Alternatively, userDataAccess.done() above may be responsible to reset Inflater (if it's InflaterDataAccess) | 516 assert lastUserData.length() == actualLen; // with no patch, data size shall be the same | 
| 515 lastUserData.reset(); | 517 userDataAccess = lastUserData; | 
| 516 // final long startMeasuring = System.currentTimeMillis(); // TIMING | 518 } else { | 
| 517 byte[] userData = patch.apply(lastUserData, actualLen); | 519 patch.read(userDataAccess); | 
| 518 // applyTime += (System.currentTimeMillis() - startMeasuring); // TIMING | 520 userDataAccess.done(); | 
| 519 patch.clear(); // do not keep any reference, allow byte[] data to be gc'd | 521 // | 
| 520 userDataAccess = new ByteArrayDataAccess(userData); | 522 // it shall be reset at the end of prev iteration, when it got assigned from userDataAccess | 
| 523 // however, actual userDataAccess and lastUserData may share Inflater object, which needs to be reset | |
| 524 // Alternatively, userDataAccess.done() above may be responsible to reset Inflater (if it's InflaterDataAccess) | |
| 525 lastUserData.reset(); | |
| 526 // final long startMeasuring = System.currentTimeMillis(); // TIMING | |
| 527 byte[] userData = patch.apply(lastUserData, actualLen); | |
| 528 // applyTime += (System.currentTimeMillis() - startMeasuring); // TIMING | |
| 529 patch.clear(); // do not keep any reference, allow byte[] data to be gc'd | |
| 530 userDataAccess = new ByteArrayDataAccess(userData); | |
| 531 } | |
| 521 } | 532 } | 
| 522 } else { | 533 } else { | 
| 523 if (inline) { | 534 if (inline) { | 
| 524 daIndex.skip(compressedLen); | 535 daIndex.skip(compressedLen); | 
| 525 } | 536 } | 
| 535 } | 546 } | 
| 536 } | 547 } | 
| 537 if (userDataAccess != null) { | 548 if (userDataAccess != null) { | 
| 538 userDataAccess.reset(); // not sure this is necessary here, as lastUserData would get reset anyway before next use. | 549 userDataAccess.reset(); // not sure this is necessary here, as lastUserData would get reset anyway before next use. | 
| 539 } | 550 } | 
| 540 if (lastUserData != null) { | 551 if (lastUserData != null && lastUserData != userDataAccess /* empty patch case, reuse of recent data in actual revision */) { | 
| 552 // release lastUserData only if we didn't reuse it in actual revision due to empty patch: | |
| 553 // empty patch means we have previous revision and didn't alter it with a patch, hence use lastUserData for userDataAccess above | |
| 541 lastUserData.done(); | 554 lastUserData.done(); | 
| 542 } | 555 } | 
| 543 lastUserData = userDataAccess; | 556 lastUserData = userDataAccess; | 
| 544 } | 557 } | 
| 545 lastRevisionRead = end; | 558 lastRevisionRead = end; | 
