Mercurial > jhg
diff 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 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/RevlogStream.java Thu Feb 23 01:06:24 2012 +0100 +++ b/src/org/tmatesoft/hg/internal/RevlogStream.java Thu Feb 23 21:53:21 2012 +0100 @@ -488,7 +488,7 @@ daData.seek(streamOffset); } final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch - if (streamDataAccess.isEmpty()) { + if (streamDataAccess.isEmpty() || compressedLen == 0) { userDataAccess = new DataAccess(); // empty } else { final byte firstByte = streamDataAccess.readByte(); @@ -498,26 +498,37 @@ } else if (firstByte == 0x75 /* 'u' */) { userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1); } else { - // 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 + // 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 + // + // although firstByte is already read from the streamDataAccess, FilterDataAccess#readByte would seek to + // initial offset before first attempt to read a byte userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen); } } - // XXX - if (patchToPrevious && !userDataAccess.isEmpty() /* Issue 22, empty patch to an empty base revision*/) { + // userDataAccess is revision content, either complete revision, patch of a previous content, or an empty patch + if (patchToPrevious) { // this is a patch - patch.read(userDataAccess); - userDataAccess.done(); - // - // it shall be reset at the end of prev iteration, when it got assigned from userDataAccess - // however, actual userDataAccess and lastUserData may share Inflater object, which needs to be reset - // Alternatively, userDataAccess.done() above may be responsible to reset Inflater (if it's InflaterDataAccess) - lastUserData.reset(); -// final long startMeasuring = System.currentTimeMillis(); // TIMING - byte[] userData = patch.apply(lastUserData, actualLen); -// applyTime += (System.currentTimeMillis() - startMeasuring); // TIMING - patch.clear(); // do not keep any reference, allow byte[] data to be gc'd - userDataAccess = new ByteArrayDataAccess(userData); + if (userDataAccess.isEmpty()) { + // Issue 22, empty patch to an empty base revision + // Issue 24, empty patch to non-empty base revision + // empty patch modifies nothing, use content of a previous revision (shall present - it's a patch here) + // + assert lastUserData.length() == actualLen; // with no patch, data size shall be the same + userDataAccess = lastUserData; + } else { + patch.read(userDataAccess); + userDataAccess.done(); + // + // it shall be reset at the end of prev iteration, when it got assigned from userDataAccess + // however, actual userDataAccess and lastUserData may share Inflater object, which needs to be reset + // Alternatively, userDataAccess.done() above may be responsible to reset Inflater (if it's InflaterDataAccess) + lastUserData.reset(); +// final long startMeasuring = System.currentTimeMillis(); // TIMING + byte[] userData = patch.apply(lastUserData, actualLen); +// applyTime += (System.currentTimeMillis() - startMeasuring); // TIMING + patch.clear(); // do not keep any reference, allow byte[] data to be gc'd + userDataAccess = new ByteArrayDataAccess(userData); + } } } else { if (inline) { @@ -537,7 +548,9 @@ if (userDataAccess != null) { userDataAccess.reset(); // not sure this is necessary here, as lastUserData would get reset anyway before next use. } - if (lastUserData != null) { + if (lastUserData != null && lastUserData != userDataAccess /* empty patch case, reuse of recent data in actual revision */) { + // release lastUserData only if we didn't reuse it in actual revision due to empty patch: + // empty patch means we have previous revision and didn't alter it with a patch, hence use lastUserData for userDataAccess above lastUserData.done(); } lastUserData = userDataAccess;