Mercurial > hg4j
diff src/org/tmatesoft/hg/repo/HgDataFile.java @ 275:6d1804fe0ed7
Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 25 Aug 2011 21:35:03 +0200 |
parents | 2fb439375ddc |
children | 6355ecda1f08 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgDataFile.java Thu Aug 25 03:57:39 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgDataFile.java Thu Aug 25 21:35:03 2011 +0200 @@ -79,8 +79,26 @@ return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names? } - public int length(Nodeid nodeid) { - return content.dataLength(getLocalRevision(nodeid)); + /** + * @return size of the file content at the given revision + */ + public int length(Nodeid nodeid) throws HgDataStreamException { + return length(getLocalRevision(nodeid)); + + } + + /** + * @return size of the file content at the revision identified by local revision number. + */ + public int length(int localRev) throws HgDataStreamException { + if (metadata == null || !metadata.checked(localRev)) { + checkAndRecordMetadata(localRev); + } + final int dataLen = content.dataLength(localRev); + if (metadata.known(localRev)) { + return dataLen - metadata.dataOffset(localRev); + } + return dataLen; } /** @@ -258,27 +276,7 @@ public boolean isCopy() throws HgDataStreamException { if (metadata == null || !metadata.checked(0)) { - // content() always initializes metadata. - // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better. - // Alternatively, may parameterize MetadataContentPipe to do prepare only. - // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms - // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms - // (compared to command-line counterpart of 190ms) - try { - content(0, new ByteChannel() { // No-op channel - public int write(ByteBuffer buffer) throws IOException, CancelledException { - // pretend we consumed whole buffer -// int rv = buffer.remaining(); -// buffer.position(buffer.limit()); -// return rv; - throw new CancelledException(); - } - }); - } catch (CancelledException ex) { - // it's ok, we did that - } catch (Exception ex) { - throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex); - } + checkAndRecordMetadata(0); } if (!metadata.known(0)) { return false; @@ -308,6 +306,26 @@ sb.append(')'); return sb.toString(); } + + private void checkAndRecordMetadata(int localRev) throws HgDataStreamException { + // content() always initializes metadata. + // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better. + // Alternatively, may parameterize MetadataContentPipe to do prepare only. + // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms + // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms + // (compared to command-line counterpart of 190ms) + try { + content(localRev, new ByteChannel() { // No-op channel + public int write(ByteBuffer buffer) throws IOException, CancelledException { + throw new CancelledException(); + } + }); + } catch (CancelledException ex) { + // it's ok, we did that + } catch (Exception ex) { + throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex).setRevisionNumber(localRev); + } + } private static final class MetadataEntry { private final String entry;