annotate hg4j/src/main/java/org/tmatesoft/hg/internal/RevlogStream.java @ 213:6ec4af642ba8 gradle

Project uses Gradle for build - actual changes
author Alexander Kitaev <kitaev@gmail.com>
date Tue, 10 May 2011 10:52:53 +0200
parents
children
rev   line source
213
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
1 /*
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2010-2011 TMate Software Ltd
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
3 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
7 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
12 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
16 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
18
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
19 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
20 import static org.tmatesoft.hg.repo.HgRepository.TIP;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
21
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
22 import java.io.File;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
23 import java.io.IOException;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
24 import java.util.ArrayList;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
25 import java.util.LinkedList;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
26 import java.util.List;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
27
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
28 import org.tmatesoft.hg.core.HgBadStateException;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
29 import org.tmatesoft.hg.core.Nodeid;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
30 import org.tmatesoft.hg.repo.HgRepository;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
31
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
32
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
33 /**
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
34 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations),
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
35 * or numerous RevlogStream with separate representation of the underlying data (cached, lazy ChunkStream)?
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
36 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
37 * @see http://mercurial.selenic.com/wiki/Revlog
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
38 * @see http://mercurial.selenic.com/wiki/RevlogNG
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
39 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
40 * @author Artem Tikhomirov
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
41 * @author TMate Software Ltd.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
42 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
43 public class RevlogStream {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
44
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
45 /*
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
46 * makes sense for index with inline data only - actual offset of the record in the .i file (record entry + revision * record size))
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
47 *
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
48 * long[] in fact (there are 8-bytes field in the revlog)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
49 * However, (a) DataAccess currently doesn't operate with long seek/length
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
50 * and, of greater significance, (b) files with inlined data are designated for smaller files,
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
51 * guess, about 130 Kb, and offset there won't ever break int capacity
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
52 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
53 private int[] indexRecordOffset;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
54 private int[] baseRevisions;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
55 private boolean inline = false;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
56 private final File indexFile;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
57 private final DataAccessProvider dataAccess;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
58
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
59 // if we need anything else from HgRepo, might replace DAP parameter with HgRepo and query it for DAP.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
60 public RevlogStream(DataAccessProvider dap, File indexFile) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
61 this.dataAccess = dap;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
62 this.indexFile = indexFile;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
63 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
64
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
65 /*package*/ DataAccess getIndexStream() {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
66 return dataAccess.create(indexFile);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
67 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
68
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
69 /*package*/ DataAccess getDataStream() {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
70 final String indexName = indexFile.getName();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
71 File dataFile = new File(indexFile.getParentFile(), indexName.substring(0, indexName.length() - 1) + "d");
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
72 return dataAccess.create(dataFile);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
73 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
74
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
75 public int revisionCount() {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
76 initOutline();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
77 return baseRevisions.length;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
78 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
79
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
80 public int dataLength(int revision) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
81 // XXX in fact, use of iterate() instead of this implementation may be quite reasonable.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
82 //
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
83 final int indexSize = revisionCount();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
84 DataAccess daIndex = getIndexStream(); // XXX may supply a hint that I'll need really few bytes of data (although at some offset)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
85 if (revision == TIP) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
86 revision = indexSize - 1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
87 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
88 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
89 int recordOffset = getIndexOffsetInt(revision);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
90 daIndex.seek(recordOffset + 12); // 6+2+4
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
91 int actualLen = daIndex.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
92 return actualLen;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
93 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
94 ex.printStackTrace(); // log error. FIXME better handling
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
95 throw new IllegalStateException(ex);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
96 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
97 daIndex.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
98 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
99 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
100
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
101 public byte[] nodeid(int revision) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
102 final int indexSize = revisionCount();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
103 if (revision == TIP) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
104 revision = indexSize - 1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
105 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
106 if (revision < 0 || revision >= indexSize) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
107 throw new IllegalArgumentException(Integer.toString(revision));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
108 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
109 DataAccess daIndex = getIndexStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
110 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
111 int recordOffset = getIndexOffsetInt(revision);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
112 daIndex.seek(recordOffset + 32);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
113 byte[] rv = new byte[20];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
114 daIndex.readBytes(rv, 0, 20);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
115 return rv;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
116 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
117 ex.printStackTrace();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
118 throw new IllegalStateException();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
119 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
120 daIndex.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
121 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
122 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
123
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
124 public int linkRevision(int revision) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
125 final int last = revisionCount() - 1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
126 if (revision == TIP) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
127 revision = last;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
128 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
129 if (revision < 0 || revision > last) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
130 throw new IllegalArgumentException(Integer.toString(revision));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
131 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
132 DataAccess daIndex = getIndexStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
133 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
134 int recordOffset = getIndexOffsetInt(revision);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
135 daIndex.seek(recordOffset + 20);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
136 int linkRev = daIndex.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
137 return linkRev;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
138 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
139 ex.printStackTrace();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
140 throw new IllegalStateException();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
141 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
142 daIndex.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
143 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
144 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
145
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
146 // Perhaps, RevlogStream should be limited to use of plain int revisions for access,
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
147 // while Nodeids should be kept on the level up, in Revlog. Guess, Revlog better keep
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
148 // map of nodeids, and once this comes true, we may get rid of this method.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
149 // Unlike its counterpart, {@link Revlog#getLocalRevisionNumber()}, doesn't fail with exception if node not found,
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
150 /**
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
151 * @return integer in [0..revisionCount()) or {@link HgRepository#BAD_REVISION} if not found
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
152 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
153 public int findLocalRevisionNumber(Nodeid nodeid) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
154 // XXX this one may be implemented with iterate() once there's mechanism to stop iterations
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
155 final int indexSize = revisionCount();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
156 DataAccess daIndex = getIndexStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
157 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
158 byte[] nodeidBuf = new byte[20];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
159 for (int i = 0; i < indexSize; i++) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
160 daIndex.skip(8);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
161 int compressedLen = daIndex.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
162 daIndex.skip(20);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
163 daIndex.readBytes(nodeidBuf, 0, 20);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
164 if (nodeid.equalsTo(nodeidBuf)) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
165 return i;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
166 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
167 daIndex.skip(inline ? 12 + compressedLen : 12);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
168 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
169 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
170 ex.printStackTrace(); // log error. FIXME better handling
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
171 throw new IllegalStateException(ex);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
172 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
173 daIndex.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
174 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
175 return BAD_REVISION;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
176 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
177
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
178
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
179 private final int REVLOGV1_RECORD_SIZE = 64;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
180
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
181 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
182 // ? boolean needsNodeid
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
183 public void iterate(int start, int end, boolean needData, Inspector inspector) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
184 initOutline();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
185 final int indexSize = revisionCount();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
186 if (indexSize == 0) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
187 return;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
188 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
189 if (end == TIP) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
190 end = indexSize - 1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
191 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
192 if (start == TIP) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
193 start = indexSize - 1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
194 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
195 if (start < 0 || start >= indexSize) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
196 throw new IllegalArgumentException(String.format("Bad left range boundary %d in [0..%d]", start, indexSize-1));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
197 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
198 if (end < start || end >= indexSize) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
199 throw new IllegalArgumentException(String.format("Bad right range boundary %d in [0..%d]", end, indexSize-1));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
200 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
201 // XXX may cache [start .. end] from index with a single read (pre-read)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
202
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
203 DataAccess daIndex = null, daData = null;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
204 daIndex = getIndexStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
205 if (needData && !inline) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
206 daData = getDataStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
207 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
208 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
209 byte[] nodeidBuf = new byte[20];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
210 DataAccess lastUserData = null;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
211 int i;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
212 boolean extraReadsToBaseRev = false;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
213 if (needData && getBaseRevision(start) < start) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
214 i = getBaseRevision(start);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
215 extraReadsToBaseRev = true;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
216 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
217 i = start;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
218 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
219
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
220 daIndex.seek(getIndexOffsetInt(i));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
221 for (; i <= end; i++ ) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
222 if (inline && needData) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
223 // inspector reading data (though FilterDataAccess) may have affected index position
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
224 daIndex.seek(getIndexOffsetInt(i));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
225 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
226 long l = daIndex.readLong(); // 0
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
227 long offset = i == 0 ? 0 : (l >>> 16);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
228 @SuppressWarnings("unused")
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
229 int flags = (int) (l & 0X0FFFF);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
230 int compressedLen = daIndex.readInt(); // +8
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
231 int actualLen = daIndex.readInt(); // +12
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
232 int baseRevision = daIndex.readInt(); // +16
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
233 int linkRevision = daIndex.readInt(); // +20
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
234 int parent1Revision = daIndex.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
235 int parent2Revision = daIndex.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
236 // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
237 daIndex.readBytes(nodeidBuf, 0, 20); // +32
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
238 daIndex.skip(12);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
239 DataAccess userDataAccess = null;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
240 if (needData) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
241 final byte firstByte;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
242 int streamOffset;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
243 DataAccess streamDataAccess;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
244 if (inline) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
245 streamDataAccess = daIndex;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
246 streamOffset = getIndexOffsetInt(i) + REVLOGV1_RECORD_SIZE; // don't need to do seek as it's actual position in the index stream
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
247 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
248 streamOffset = (int) offset;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
249 streamDataAccess = daData;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
250 daData.seek(streamOffset);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
251 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
252 final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
253 firstByte = streamDataAccess.readByte();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
254 if (firstByte == 0x78 /* 'x' */) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
255 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, patchToPrevious ? -1 : actualLen);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
256 } else if (firstByte == 0x75 /* 'u' */) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
257 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
258 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
259 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0'
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
260 // but I don't see reason not to return data as is
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
261 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
262 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
263 // XXX
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
264 if (patchToPrevious) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
265 // this is a patch
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
266 LinkedList<PatchRecord> patches = new LinkedList<PatchRecord>();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
267 while (!userDataAccess.isEmpty()) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
268 PatchRecord pr = PatchRecord.read(userDataAccess);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
269 // System.out.printf("PatchRecord:%d %d %d\n", pr.start, pr.end, pr.len);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
270 patches.add(pr);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
271 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
272 userDataAccess.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
273 //
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
274 byte[] userData = apply(lastUserData, actualLen, patches);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
275 userDataAccess = new ByteArrayDataAccess(userData);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
276 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
277 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
278 if (inline) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
279 daIndex.skip(compressedLen);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
280 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
281 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
282 if (!extraReadsToBaseRev || i >= start) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
283 inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, userDataAccess);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
284 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
285 if (userDataAccess != null) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
286 userDataAccess.reset();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
287 if (lastUserData != null) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
288 lastUserData.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
289 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
290 lastUserData = userDataAccess;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
291 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
292 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
293 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
294 throw new HgBadStateException(ex); // FIXME need better handling
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
295 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
296 daIndex.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
297 if (daData != null) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
298 daData.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
299 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
300 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
301 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
302
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
303 private int getBaseRevision(int revision) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
304 return baseRevisions[revision];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
305 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
306
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
307 /**
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
308 * @return offset of the revision's record in the index (.i) stream
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
309 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
310 private int getIndexOffsetInt(int revision) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
311 return inline ? indexRecordOffset[revision] : revision * REVLOGV1_RECORD_SIZE;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
312 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
313
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
314 private void initOutline() {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
315 if (baseRevisions != null && baseRevisions.length > 0) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
316 return;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
317 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
318 ArrayList<Integer> resBases = new ArrayList<Integer>();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
319 ArrayList<Integer> resOffsets = new ArrayList<Integer>();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
320 DataAccess da = getIndexStream();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
321 try {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
322 if (da.isEmpty()) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
323 // do not fail with exception if stream is empty, it's likely intentional
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
324 baseRevisions = new int[0];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
325 return;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
326 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
327 int versionField = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
328 da.readInt(); // just to skip next 4 bytes of offset + flags
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
329 final int INLINEDATA = 1 << 16;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
330 inline = (versionField & INLINEDATA) != 0;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
331 long offset = 0; // first offset is always 0, thus Hg uses it for other purposes
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
332 while(true) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
333 int compressedLen = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
334 // 8+4 = 12 bytes total read here
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
335 @SuppressWarnings("unused")
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
336 int actualLen = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
337 int baseRevision = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
338 // 12 + 8 = 20 bytes read here
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
339 // int linkRevision = di.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
340 // int parent1Revision = di.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
341 // int parent2Revision = di.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
342 // byte[] nodeid = new byte[32];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
343 resBases.add(baseRevision);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
344 if (inline) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
345 int o = (int) offset;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
346 if (o != offset) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
347 // just in case, can't happen, ever, unless HG (or some other bad tool) produces index file
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
348 // with inlined data of size greater than 2 Gb.
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
349 throw new HgBadStateException("Data too big, offset didn't fit to sizeof(int)");
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
350 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
351 resOffsets.add(o + REVLOGV1_RECORD_SIZE * resOffsets.size());
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
352 da.skip(3*4 + 32 + compressedLen); // Check: 44 (skip) + 20 (read) = 64 (total RevlogNG record size)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
353 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
354 da.skip(3*4 + 32);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
355 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
356 if (da.isEmpty()) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
357 // fine, done then
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
358 baseRevisions = toArray(resBases);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
359 if (inline) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
360 indexRecordOffset = toArray(resOffsets);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
361 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
362 break;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
363 } else {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
364 // start reading next record
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
365 long l = da.readLong();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
366 offset = l >>> 16;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
367 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
368 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
369 } catch (IOException ex) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
370 ex.printStackTrace(); // log error
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
371 // too bad, no outline then, but don't fail with NPE
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
372 baseRevisions = new int[0];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
373 } finally {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
374 da.done();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
375 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
376 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
377
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
378 private static int[] toArray(List<Integer> l) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
379 int[] rv = new int[l.size()];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
380 for (int i = 0; i < rv.length; i++) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
381 rv[i] = l.get(i);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
382 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
383 return rv;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
384 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
385
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
386
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
387 // mpatch.c : apply()
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
388 // FIXME need to implement patch merge (fold, combine, gather and discard from aforementioned mpatch.[c|py]), also see Revlog and Mercurial PDF
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
389 public/*for HgBundle; until moved to better place*/static byte[] apply(DataAccess baseRevisionContent, int outcomeLen, List<PatchRecord> patch) throws IOException {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
390 int last = 0, destIndex = 0;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
391 if (outcomeLen == -1) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
392 outcomeLen = baseRevisionContent.length();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
393 for (PatchRecord pr : patch) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
394 outcomeLen += pr.start - last + pr.len;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
395 last = pr.end;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
396 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
397 outcomeLen -= last;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
398 last = 0;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
399 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
400 byte[] rv = new byte[outcomeLen];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
401 for (PatchRecord pr : patch) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
402 baseRevisionContent.seek(last);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
403 baseRevisionContent.readBytes(rv, destIndex, pr.start-last);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
404 destIndex += pr.start - last;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
405 System.arraycopy(pr.data, 0, rv, destIndex, pr.data.length);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
406 destIndex += pr.data.length;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
407 last = pr.end;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
408 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
409 baseRevisionContent.seek(last);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
410 baseRevisionContent.readBytes(rv, destIndex, (int) (baseRevisionContent.length() - last));
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
411 return rv;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
412 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
413
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
414 // @see http://mercurial.selenic.com/wiki/BundleFormat, in Changelog group description
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
415 public static class PatchRecord {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
416 /*
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
417 Given there are pr1 and pr2:
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
418 pr1.start to pr1.end will be replaced with pr's data (of pr1.len)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
419 pr1.end to pr2.start gets copied from base
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
420 */
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
421 public int start, end, len;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
422 public byte[] data;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
423
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
424 // TODO consider PatchRecord that only records data position (absolute in data source), and acquires data as needed
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
425 private PatchRecord(int p1, int p2, int length, byte[] src) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
426 start = p1;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
427 end = p2;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
428 len = length;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
429 data = src;
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
430 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
431
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
432 /*package-local*/ static PatchRecord read(byte[] data, int offset) {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
433 final int x = offset; // shorthand
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
434 int p1 = ((data[x] & 0xFF)<< 24) | ((data[x+1] & 0xFF) << 16) | ((data[x+2] & 0xFF) << 8) | (data[x+3] & 0xFF);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
435 int p2 = ((data[x+4] & 0xFF) << 24) | ((data[x+5] & 0xFF) << 16) | ((data[x+6] & 0xFF) << 8) | (data[x+7] & 0xFF);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
436 int len = ((data[x+8] & 0xFF) << 24) | ((data[x+9] & 0xFF) << 16) | ((data[x+10] & 0xFF) << 8) | (data[x+11] & 0xFF);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
437 byte[] dataCopy = new byte[len];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
438 System.arraycopy(data, x+12, dataCopy, 0, len);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
439 return new PatchRecord(p1, p2, len, dataCopy);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
440 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
441
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
442 public /*for HgBundle*/ static PatchRecord read(DataAccess da) throws IOException {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
443 int p1 = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
444 int p2 = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
445 int len = da.readInt();
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
446 byte[] src = new byte[len];
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
447 da.readBytes(src, 0, len);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
448 return new PatchRecord(p1, p2, len, src);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
449 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
450 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
451
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
452 // FIXME byte[] data might be too expensive, for few usecases it may be better to have intermediate Access object (when we don't need full data
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
453 // instantly - e.g. calculate hash, or comparing two revisions
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
454 public interface Inspector {
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
455 // XXX boolean retVal to indicate whether to continue?
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
456 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call)
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
457 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
458 void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data);
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
459 }
6ec4af642ba8 Project uses Gradle for build - actual changes
Alexander Kitaev <kitaev@gmail.com>
parents:
diff changeset
460 }