annotate src/org/tmatesoft/hg/repo/HgDataFile.java @ 326:d42a45a2c9d6

Alternative tag collection approach for a file history
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 04 Oct 2011 06:28:01 +0200
parents 4c7e3ba67213
children a674b8590362
rev   line source
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
1 /*
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
2 * Copyright (c) 2010-2011 TMate Software Ltd
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
3 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
4 * This program is free software; you can redistribute it and/or modify
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
5 * it under the terms of the GNU General Public License as published by
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
6 * the Free Software Foundation; version 2 of the License.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
7 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
8 * This program is distributed in the hope that it will be useful,
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
11 * GNU General Public License for more details.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
12 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
13 * For information on how to redistribute this software under
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
14 * the terms of a license other than GNU General Public License
102
a3a2e5deb320 Updated contact address to support@hg4j.com
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 88
diff changeset
15 * contact TMate Software at support@hg4j.com
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
17 package org.tmatesoft.hg.repo;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
19 import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision;
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
20 import static org.tmatesoft.hg.repo.HgRepository.*;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
21
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
22 import java.io.ByteArrayOutputStream;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
23 import java.io.File;
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
24 import java.io.FileInputStream;
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
25 import java.io.IOException;
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
26 import java.nio.ByteBuffer;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
27 import java.nio.channels.FileChannel;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
28 import java.util.ArrayList;
240
29231022fec8 Do not expect file history to be ordered
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 237
diff changeset
29 import java.util.Arrays;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
30 import java.util.Collection;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
31 import java.util.Collections;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
32 import java.util.List;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
33
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
34 import org.tmatesoft.hg.core.HgDataStreamException;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
35 import org.tmatesoft.hg.core.HgException;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
36 import org.tmatesoft.hg.core.Nodeid;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
37 import org.tmatesoft.hg.internal.DataAccess;
121
b1d6208fb517 Conditionally apply filters to file content
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 115
diff changeset
38 import org.tmatesoft.hg.internal.FilterByteChannel;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
39 import org.tmatesoft.hg.internal.FilterDataAccess;
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
40 import org.tmatesoft.hg.internal.IntMap;
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
41 import org.tmatesoft.hg.internal.RevlogStream;
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
42 import org.tmatesoft.hg.util.ByteChannel;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
43 import org.tmatesoft.hg.util.CancelSupport;
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
44 import org.tmatesoft.hg.util.CancelledException;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
45 import org.tmatesoft.hg.util.Pair;
133
4a948ec83980 core.Path to util.Path as it's not Hg repo dependant
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 129
diff changeset
46 import org.tmatesoft.hg.util.Path;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
47 import org.tmatesoft.hg.util.ProgressSupport;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
48
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 3
diff changeset
49
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
50
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
51 /**
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
52 * ? name:HgFileNode?
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
53 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
54 * @author Artem Tikhomirov
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
55 * @author TMate Software Ltd.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 */
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 public class HgDataFile extends Revlog {
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
58
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
59 // absolute from repo root?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
60 // slashes, unix-style?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
61 // repo location agnostic, just to give info to user, not to access real storage
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
62 private final Path path;
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
63 private Metadata metadata; // get initialized on first access to file content.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
65 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath, RevlogStream content) {
21
e929cecae4e1 Refactor to move revlog content to base class
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 17
diff changeset
66 super(hgRepo, content);
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
67 path = filePath;
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
68 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
69
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
70 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath) {
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
71 super(hgRepo);
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
72 path = filePath;
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
73 }
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
74
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
75 // exists is not the best name possible. now it means no file with such name was ever known to the repo.
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
76 // it might be confused with files existed before but lately removed.
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
77 public boolean exists() {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
78 return content != null; // XXX need better impl
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
79 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
80
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
81 // human-readable (i.e. "COPYING", not "store/data/_c_o_p_y_i_n_g.i")
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
82 public Path getPath() {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
83 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names?
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
86 /**
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
87 * @return size of the file content at the given revision
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
88 */
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
89 public int length(Nodeid nodeid) throws HgDataStreamException {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
90 return length(getLocalRevision(nodeid));
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
91
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
92 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
93
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
94 /**
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
95 * @return size of the file content at the revision identified by local revision number.
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
96 */
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
97 public int length(int localRev) throws HgDataStreamException {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
98 if (metadata == null || !metadata.checked(localRev)) {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
99 checkAndRecordMetadata(localRev);
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
100 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
101 final int dataLen = content.dataLength(localRev);
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
102 if (metadata.known(localRev)) {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
103 return dataLen - metadata.dataOffset(localRev);
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
104 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
105 return dataLen;
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
106 }
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
107
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
108 /**
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
109 * Reads content of the file from working directory. If file present in the working directory, its actual content without
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
110 * any filters is supplied through the sink. If file does not exist in the working dir, this method provides content of a file
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
111 * as if it would be refreshed in the working copy, i.e. its corresponding revision
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
112 * (XXX according to dirstate? file tip?) is read from the repository, and filters repo -> working copy get applied.
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
113 *
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
114 * @param sink where to pipe content to
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
115 * @throws HgDataStreamException to indicate troubles reading repository file
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
116 * @throws CancelledException if operation was cancelled
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
117 */
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
118 public void workingCopy(ByteChannel sink) throws HgDataStreamException, CancelledException {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
119 File f = getRepo().getFile(this);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
120 if (f.exists()) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
121 final CancelSupport cs = CancelSupport.Factory.get(sink);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
122 final ProgressSupport progress = ProgressSupport.Factory.get(sink);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
123 final long flength = f.length();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
124 final int bsize = (int) Math.min(flength, 32*1024);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
125 progress.start((int) (flength > Integer.MAX_VALUE ? flength >>> 15 /*32 kb buf size*/ : flength));
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
126 ByteBuffer buf = ByteBuffer.allocate(bsize);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
127 FileChannel fc = null;
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
128 try {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
129 fc = new FileInputStream(f).getChannel();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
130 while (fc.read(buf) != -1) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
131 cs.checkCancelled();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
132 buf.flip();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
133 int consumed = sink.write(buf);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
134 progress.worked(flength > Integer.MAX_VALUE ? 1 : consumed);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
135 buf.compact();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
136 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
137 } catch (IOException ex) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
138 throw new HgDataStreamException(getPath(), ex);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
139 } finally {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
140 progress.done();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
141 if (fc != null) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
142 try {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
143 fc.close();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
144 } catch (IOException ex) {
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 277
diff changeset
145 getRepo().getContext().getLog().info(getClass(), ex, null);
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
146 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
147 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
148 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
149 } else {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
150 contentWithFilters(TIP, sink);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
151 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
152 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
153
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
154 // public void content(int revision, ByteChannel sink, boolean applyFilters) throws HgDataStreamException, IOException, CancelledException {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
155 // byte[] content = content(revision);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
156 // final CancelSupport cancelSupport = CancelSupport.Factory.get(sink);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
157 // final ProgressSupport progressSupport = ProgressSupport.Factory.get(sink);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
158 // ByteBuffer buf = ByteBuffer.allocate(512);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
159 // int left = content.length;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
160 // progressSupport.start(left);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
161 // int offset = 0;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
162 // cancelSupport.checkCancelled();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
163 // ByteChannel _sink = applyFilters ? new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())) : sink;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
164 // do {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
165 // buf.put(content, offset, Math.min(left, buf.remaining()));
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
166 // buf.flip();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
167 // cancelSupport.checkCancelled();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
168 // // XXX I may not rely on returned number of bytes but track change in buf position instead.
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
169 // int consumed = _sink.write(buf);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
170 // buf.compact();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
171 // offset += consumed;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
172 // left -= consumed;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
173 // progressSupport.worked(consumed);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
174 // } while (left > 0);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
175 // progressSupport.done(); // XXX shall specify whether #done() is invoked always or only if completed successfully.
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
176 // }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
177
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
178 /*XXX not sure distinct method contentWithFilters() is the best way to do, perhaps, callers shall add filters themselves?*/
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
179 public void contentWithFilters(int revision, ByteChannel sink) throws HgDataStreamException, CancelledException {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
180 if (revision == WORKING_COPY) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
181 workingCopy(sink); // pass un-mangled sink
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
182 } else {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
183 content(revision, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())));
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
184 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
185 }
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
186
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
187 // for data files need to check heading of the file content for possible metadata
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
188 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8-
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
189 public void content(int revision, ByteChannel sink) throws HgDataStreamException, CancelledException {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
190 if (revision == TIP) {
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
191 revision = getLastRevision();
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
192 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
193 if (revision == WORKING_COPY) {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
194 // sink is supposed to come into workingCopy without filters
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
195 // thus we shall not get here (into #content) from #contentWithFilters(WC)
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
196 workingCopy(sink);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
197 return;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
198 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
199 if (wrongLocalRevision(revision) || revision == BAD_REVISION) {
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
200 throw new IllegalArgumentException(String.valueOf(revision));
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
201 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
202 if (sink == null) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
203 throw new IllegalArgumentException();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
204 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
205 if (metadata == null) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
206 metadata = new Metadata();
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
207 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
208 ErrorHandlingInspector insp;
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
209 if (metadata.none(revision)) {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
210 insp = new ContentPipe(sink, 0);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
211 } else if (metadata.known(revision)) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
212 insp = new ContentPipe(sink, metadata.dataOffset(revision));
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
213 } else {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
214 // do not know if there's metadata
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
215 insp = new MetadataInspector(metadata, getPath(), new ContentPipe(sink, 0));
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
216 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
217 insp.checkCancelled();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
218 super.content.iterate(revision, revision, true, insp);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
219 try {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
220 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe?
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
221 } catch (HgDataStreamException ex) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
222 throw ex;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
223 } catch (IOException ex) {
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
224 throw new HgDataStreamException(getPath(), ex).setRevisionNumber(revision);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
225 } catch (HgException ex) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
226 // shall not happen, unless we changed ContentPipe or its subclass
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 163
diff changeset
227 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
228 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
229 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
230
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
231 private static class HistoryNode {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
232 int changeset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
233 Nodeid cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
234 HistoryNode parent1, parent2;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
235 List<HistoryNode> children;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
236
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
237 HistoryNode(int cs, HistoryNode p1, HistoryNode p2) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
238 changeset = cs;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
239 parent1 = p1;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
240 parent2 = p2;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
241 if (p1 != null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
242 p1.addChild(this);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
243 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
244 if (p2 != null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
245 p2.addChild(this);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
246 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
247 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
248
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
249 Nodeid changesetRevision() {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
250 assert cset != null : "we initialize all csets prior to use";
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
251 return cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
252 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
253
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
254 void addChild(HistoryNode child) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
255 if (children == null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
256 children = new ArrayList<HistoryNode>(2);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
257 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
258 children.add(child);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
259 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
260 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
261
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
262 public void history(HgChangelog.TreeInspector inspector) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
263 final CancelSupport cancelSupport = CancelSupport.Factory.get(inspector);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
264 try {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
265 final boolean[] needsSorting = { false };
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
266 final HistoryNode[] completeHistory = new HistoryNode[getRevisionCount()];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
267 final int[] commitRevisions = new int[completeHistory.length];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
268 RevlogStream.Inspector insp = new RevlogStream.Inspector() {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
269 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
270 if (revisionNumber > 0) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
271 if (commitRevisions[revisionNumber-1] > linkRevision) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
272 needsSorting[0] = true;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
273 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
274 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
275 commitRevisions[revisionNumber] = linkRevision;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
276 HistoryNode p1 = null, p2 = null;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
277 if (parent1Revision != -1) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
278 p1 = completeHistory[parent1Revision];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
279 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
280 if (parent2Revision != -1) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
281 p2 = completeHistory[parent2Revision];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
282 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
283 completeHistory[revisionNumber] = new HistoryNode(linkRevision, p1, p2);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
284 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
285 };
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
286 content.iterate(0, getLastRevision(), false, insp);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
287 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
288 if (needsSorting[0]) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
289 Arrays.sort(commitRevisions);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
290 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
291 // read changeset revisions at once (to avoid numerous changelog.getRevision reads)
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
292 // but just nodeids, not RawChangeset (changelog.iterate(data=false)
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
293 ArrayList<Nodeid> changesetRevisions = new ArrayList<Nodeid>(commitRevisions.length);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
294 getRepo().getChangelog().getRevisionsInternal(changesetRevisions, commitRevisions);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
295 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
296 // assign them to corresponding HistoryNodes
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
297 for (int i = 0; i < completeHistory.length; i++ ) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
298 final HistoryNode n = completeHistory[i];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
299 if (needsSorting[0]) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
300 int x = Arrays.binarySearch(commitRevisions, n.changeset);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
301 assert x >= 0;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
302 n.cset = changesetRevisions.get(x);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
303 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
304 // commit revisions were not sorted, may use original index directly
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
305 n.cset = changesetRevisions.get(i);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
306 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
307 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
308 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
309 // XXX shall sort completeHistory according to changeset numbers?
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
310 for (int i = 0; i < completeHistory.length; i++ ) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
311 final HistoryNode n = completeHistory[i];
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
312 HistoryNode p;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
313 Nodeid p1, p2;
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
314 if ((p = n.parent1) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
315 p1 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
316 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
317 p1 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
318 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
319 if ((p= n.parent2) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
320 p2 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
321 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
322 p2 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
323 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
324 final Pair<Nodeid, Nodeid> parentChangesets = new Pair<Nodeid, Nodeid>(p1, p2);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
325 final List<Nodeid> childChangesets;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
326 if (n.children == null) {
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
327 childChangesets = Collections.emptyList();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
328 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
329 Nodeid[] revisions = new Nodeid[n.children.size()];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
330 int j = 0;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
331 for (HistoryNode hn : n.children) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
332 revisions[j++] = hn.changesetRevision();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
333 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
334 childChangesets = Arrays.asList(revisions);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
335 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
336 inspector.next(n.changesetRevision(), parentChangesets, childChangesets);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
337 cancelSupport.checkCancelled();
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
338 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
339 } catch (CancelledException ex) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
340 return;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
341 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
342 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
343
129
645829962785 core.Cset renamed to HgChangeset; repo.Changeset moved into HgChangelog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 121
diff changeset
344 public void history(HgChangelog.Inspector inspector) {
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
345 history(0, getLastRevision(), inspector);
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
346 }
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
347
129
645829962785 core.Cset renamed to HgChangeset; repo.Changeset moved into HgChangelog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 121
diff changeset
348 public void history(int start, int end, HgChangelog.Inspector inspector) {
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
349 if (!exists()) {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
350 throw new IllegalStateException("Can't get history of invalid repository file node");
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
351 }
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
352 final int last = getLastRevision();
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
353 if (end == TIP) {
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
354 end = last;
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
355 }
300
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
356 if (start == TIP) {
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
357 start = last;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
358 }
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
359 HgInternals.checkRevlogRange(start, end, last);
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
360
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
361 final int[] commitRevisions = new int[end - start + 1];
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
362 final boolean[] needsSorting = { false };
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
363 RevlogStream.Inspector insp = new RevlogStream.Inspector() {
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
364 int count = 0;
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
365 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
366 if (count > 0) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
367 if (commitRevisions[count -1] > linkRevision) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
368 needsSorting[0] = true;
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
369 }
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
370 }
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
371 commitRevisions[count++] = linkRevision;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
372 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
373 };
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
374 content.iterate(start, end, false, insp);
233
1d389c0cb0a5 Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 215
diff changeset
375 final HgChangelog changelog = getRepo().getChangelog();
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
376 if (needsSorting[0]) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
377 // automatic tools (svnmerge?) produce unnatural file history
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
378 // (e.g. cpython/Lib/doctest.py, revision 164 points to cset 63509, 165 - to 38453)
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
379 Arrays.sort(commitRevisions);
233
1d389c0cb0a5 Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 215
diff changeset
380 }
245
2fb439375ddc Avoid sorting revision range twice
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 242
diff changeset
381 changelog.rangeInternal(inspector, commitRevisions);
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
382 }
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
383
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
384 // for a given local revision of the file, find out local revision in the changelog
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
385 public int getChangesetLocalRevision(int revision) {
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
386 return content.linkRevision(revision);
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
387 }
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
388
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
389 public Nodeid getChangesetRevision(Nodeid nid) {
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
390 int changelogRevision = getChangesetLocalRevision(getLocalRevision(nid));
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
391 return getRepo().getChangelog().getRevision(changelogRevision);
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
392 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
393
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
394 public boolean isCopy() throws HgDataStreamException {
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
395 if (metadata == null || !metadata.checked(0)) {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
396 checkAndRecordMetadata(0);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
397 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
398 if (!metadata.known(0)) {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
399 return false;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
400 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
401 return metadata.find(0, "copy") != null;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
402 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
403
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
404 public Path getCopySourceName() throws HgDataStreamException {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
405 if (isCopy()) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
406 return Path.create(metadata.find(0, "copy"));
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
407 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
408 throw new UnsupportedOperationException(); // XXX REVISIT, think over if Exception is good (clients would check isCopy() anyway, perhaps null is sufficient?)
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
409 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
410
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
411 public Nodeid getCopySourceRevision() throws HgDataStreamException {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
412 if (isCopy()) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
413 return Nodeid.fromAscii(metadata.find(0, "copyrev")); // XXX reuse/cache Nodeid
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
414 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
415 throw new UnsupportedOperationException();
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
416 }
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
417
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
418 @Override
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
419 public String toString() {
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
420 StringBuilder sb = new StringBuilder(getClass().getSimpleName());
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
421 sb.append('(');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
422 sb.append(getPath());
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
423 sb.append(')');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
424 return sb.toString();
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
425 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
426
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
427 private void checkAndRecordMetadata(int localRev) throws HgDataStreamException {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
428 // content() always initializes metadata.
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
429 // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better.
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
430 // Alternatively, may parameterize MetadataContentPipe to do prepare only.
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
431 // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
432 // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
433 // (compared to command-line counterpart of 190ms)
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
434 try {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
435 content(localRev, new ByteChannel() { // No-op channel
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
436 public int write(ByteBuffer buffer) throws IOException, CancelledException {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
437 throw new CancelledException();
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
438 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
439 });
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
440 } catch (CancelledException ex) {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
441 // it's ok, we did that
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
442 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
443 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
444
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
445 private static final class MetadataEntry {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
446 private final String entry;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
447 private final int valueStart;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
448 /*package-local*/MetadataEntry(String key, String value) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
449 entry = key + value;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
450 valueStart = key.length();
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
451 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
452 /*package-local*/boolean matchKey(String key) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
453 return key.length() == valueStart && entry.startsWith(key);
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
454 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
455 // uncomment once/if needed
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
456 // public String key() {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
457 // return entry.substring(0, valueStart);
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
458 // }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
459 public String value() {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
460 return entry.substring(valueStart);
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
461 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
462 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
463
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
464 private static class Metadata {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
465 private static class Record {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
466 public final int offset;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
467 public final MetadataEntry[] entries;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
468
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
469 public Record(int off, MetadataEntry[] entr) {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
470 offset = off;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
471 entries = entr;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
472 }
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
473 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
474 // XXX sparse array needed
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
475 private final IntMap<Record> entries = new IntMap<Record>(5);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
476
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
477 private final Record NONE = new Record(-1, null); // don't want statics
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
478
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
479 // true when there's metadata for given revision
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
480 boolean known(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
481 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
482 return i != null && NONE != i;
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
483 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
484
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
485 // true when revision has been checked for metadata presence.
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
486 public boolean checked(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
487 return entries.containsKey(revision);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
488 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
489
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
490 // true when revision has been checked and found not having any metadata
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
491 boolean none(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
492 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
493 return i == NONE;
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
494 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
495
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
496 // mark revision as having no metadata.
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
497 void recordNone(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
498 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
499 if (i == NONE) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
500 return; // already there
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
501 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
502 if (i != null) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
503 throw new IllegalStateException(String.format("Trying to override Metadata state for revision %d (known offset: %d)", revision, i));
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
504 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
505 entries.put(revision, NONE);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
506 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
507
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
508 // since this is internal class, callers are supposed to ensure arg correctness (i.e. ask known() before)
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
509 int dataOffset(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
510 return entries.get(revision).offset;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
511 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
512 void add(int revision, int dataOffset, Collection<MetadataEntry> e) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
513 assert !entries.containsKey(revision);
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
514 entries.put(revision, new Record(dataOffset, e.toArray(new MetadataEntry[e.size()])));
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
515 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
516
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
517 String find(int revision, String key) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
518 for (MetadataEntry me : entries.get(revision).entries) {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
519 if (me.matchKey(key)) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
520 return me.value();
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
521 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
522 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
523 return null;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
524 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
525 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
526
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
527 private static class MetadataInspector extends ErrorHandlingInspector implements RevlogStream.Inspector {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
528 private final Metadata metadata;
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 163
diff changeset
529 private final Path fname; // need this only for error reporting
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
530 private final RevlogStream.Inspector delegate;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
531
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
532 public MetadataInspector(Metadata _metadata, Path file, RevlogStream.Inspector chain) {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
533 metadata = _metadata;
215
41a778e3fd31 Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 163
diff changeset
534 fname = file;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
535 delegate = chain;
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
536 setCancelSupport(CancelSupport.Factory.get(chain));
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
537 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
538
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
539 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
540 try {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
541 final int daLength = data.length();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
542 if (daLength < 4 || data.readByte() != 1 || data.readByte() != 10) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
543 metadata.recordNone(revisionNumber);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
544 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
545 } else {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
546 ArrayList<MetadataEntry> _metadata = new ArrayList<MetadataEntry>();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
547 int offset = parseMetadata(data, daLength, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
548 metadata.add(revisionNumber, offset, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
549 // da is in prepared state (i.e. we consumed all bytes up to metadata end).
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
550 // However, it's not safe to assume delegate won't call da.reset() for some reason,
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
551 // and we need to ensure predictable result.
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
552 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
553 data = new FilterDataAccess(data, offset, daLength - offset);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
554 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
555 if (delegate != null) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
556 delegate.next(revisionNumber, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
557 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
558 } catch (IOException ex) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
559 recordFailure(ex);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
560 } catch (HgDataStreamException ex) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
561 recordFailure(ex.setRevisionNumber(revisionNumber));
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
562 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
563 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
564
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
565 private int parseMetadata(DataAccess data, final int daLength, ArrayList<MetadataEntry> _metadata) throws IOException, HgDataStreamException {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
566 int lastEntryStart = 2;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
567 int lastColon = -1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
568 // XXX in fact, need smth like ByteArrayBuilder, similar to StringBuilder,
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
569 // which can't be used here because we can't convert bytes to chars as we read them
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
570 // (there might be multi-byte encoding), and we need to collect all bytes before converting to string
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
571 ByteArrayOutputStream bos = new ByteArrayOutputStream();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
572 String key = null, value = null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
573 boolean byteOne = false;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
574 boolean metadataIsComplete = false;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
575 for (int i = 2; i < daLength; i++) {
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
576 byte b = data.readByte();
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
577 if (b == '\n') {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
578 if (byteOne) { // i.e. \n follows 1
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
579 lastEntryStart = i+1;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
580 metadataIsComplete = true;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
581 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \n)
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
582 // if yes, need to set metadataIsComplete to true in that case as well
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
583 break;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
584 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
585 if (key == null || lastColon == -1 || i <= lastColon) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
586 throw new IllegalStateException(); // FIXME log instead and record null key in the metadata. Ex just to fail fast during dev
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
587 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
588 value = new String(bos.toByteArray()).trim();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
589 bos.reset();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
590 _metadata.add(new MetadataEntry(key, value));
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
591 key = value = null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
592 lastColon = -1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
593 lastEntryStart = i+1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
594 continue;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
595 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
596 // byteOne has to be consumed up to this line, if not yet, consume it
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
597 if (byteOne) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
598 // insert 1 we've read on previous step into the byte builder
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
599 bos.write(1);
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
600 byteOne = false;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
601 // fall-through to consume current byte
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
602 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
603 if (b == (int) ':') {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
604 assert value == null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
605 key = new String(bos.toByteArray());
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
606 bos.reset();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
607 lastColon = i;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
608 } else if (b == 1) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
609 byteOne = true;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
610 } else {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
611 bos.write(b);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
612 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
613 }
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
614 // data.isEmpty is not reliable, renamed files of size==0 keep only metadata
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
615 if (!metadataIsComplete) {
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
616 // XXX perhaps, worth a testcase (empty file, renamed, read or ask ifCopy
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
617 throw new HgDataStreamException(fname, "Metadata is not closed properly", null);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
618 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
619 return lastEntryStart;
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
620 }
322
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
621
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
622 @Override
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
623 public void checkFailed() throws HgException, IOException, CancelledException {
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
624 super.checkFailed();
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
625 if (delegate instanceof ErrorHandlingInspector) {
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
626 // XXX need to add ErrorDestination and pass it around (much like CancelSupport get passed)
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
627 // so that delegate would be able report its failures directly to caller without this hack
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
628 ((ErrorHandlingInspector) delegate).checkFailed();
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
629 }
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
630 }
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
631 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
632 }