Mercurial > jhg
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; |
