comparison 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
comparison
equal deleted inserted replaced
274:9fb50c04f03c 275:6d1804fe0ed7
77 // human-readable (i.e. "COPYING", not "store/data/_c_o_p_y_i_n_g.i") 77 // human-readable (i.e. "COPYING", not "store/data/_c_o_p_y_i_n_g.i")
78 public Path getPath() { 78 public Path getPath() {
79 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names? 79 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names?
80 } 80 }
81 81
82 public int length(Nodeid nodeid) { 82 /**
83 return content.dataLength(getLocalRevision(nodeid)); 83 * @return size of the file content at the given revision
84 */
85 public int length(Nodeid nodeid) throws HgDataStreamException {
86 return length(getLocalRevision(nodeid));
87
88 }
89
90 /**
91 * @return size of the file content at the revision identified by local revision number.
92 */
93 public int length(int localRev) throws HgDataStreamException {
94 if (metadata == null || !metadata.checked(localRev)) {
95 checkAndRecordMetadata(localRev);
96 }
97 final int dataLen = content.dataLength(localRev);
98 if (metadata.known(localRev)) {
99 return dataLen - metadata.dataOffset(localRev);
100 }
101 return dataLen;
84 } 102 }
85 103
86 /** 104 /**
87 * Reads content of the file from working directory. If file present in the working directory, its actual content without 105 * Reads content of the file from working directory. If file present in the working directory, its actual content without
88 * any filters is supplied through the sink. If file does not exist in the working dir, this method provides content of a file 106 * any filters is supplied through the sink. If file does not exist in the working dir, this method provides content of a file
256 return getRepo().getChangelog().getRevision(changelogRevision); 274 return getRepo().getChangelog().getRevision(changelogRevision);
257 } 275 }
258 276
259 public boolean isCopy() throws HgDataStreamException { 277 public boolean isCopy() throws HgDataStreamException {
260 if (metadata == null || !metadata.checked(0)) { 278 if (metadata == null || !metadata.checked(0)) {
261 // content() always initializes metadata. 279 checkAndRecordMetadata(0);
262 // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better.
263 // Alternatively, may parameterize MetadataContentPipe to do prepare only.
264 // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms
265 // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms
266 // (compared to command-line counterpart of 190ms)
267 try {
268 content(0, new ByteChannel() { // No-op channel
269 public int write(ByteBuffer buffer) throws IOException, CancelledException {
270 // pretend we consumed whole buffer
271 // int rv = buffer.remaining();
272 // buffer.position(buffer.limit());
273 // return rv;
274 throw new CancelledException();
275 }
276 });
277 } catch (CancelledException ex) {
278 // it's ok, we did that
279 } catch (Exception ex) {
280 throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex);
281 }
282 } 280 }
283 if (!metadata.known(0)) { 281 if (!metadata.known(0)) {
284 return false; 282 return false;
285 } 283 }
286 return metadata.find(0, "copy") != null; 284 return metadata.find(0, "copy") != null;
305 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); 303 StringBuilder sb = new StringBuilder(getClass().getSimpleName());
306 sb.append('('); 304 sb.append('(');
307 sb.append(getPath()); 305 sb.append(getPath());
308 sb.append(')'); 306 sb.append(')');
309 return sb.toString(); 307 return sb.toString();
308 }
309
310 private void checkAndRecordMetadata(int localRev) throws HgDataStreamException {
311 // content() always initializes metadata.
312 // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better.
313 // Alternatively, may parameterize MetadataContentPipe to do prepare only.
314 // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms
315 // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms
316 // (compared to command-line counterpart of 190ms)
317 try {
318 content(localRev, new ByteChannel() { // No-op channel
319 public int write(ByteBuffer buffer) throws IOException, CancelledException {
320 throw new CancelledException();
321 }
322 });
323 } catch (CancelledException ex) {
324 // it's ok, we did that
325 } catch (Exception ex) {
326 throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex).setRevisionNumber(localRev);
327 }
310 } 328 }
311 329
312 private static final class MetadataEntry { 330 private static final class MetadataEntry {
313 private final String entry; 331 private final String entry;
314 private final int valueStart; 332 private final int valueStart;