Mercurial > hg4j
annotate src/org/tmatesoft/hg/internal/RevlogStream.java @ 242:ad6a046943be
Improved reading of sparse revisions from a revlog
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 23 Jun 2011 15:19:07 +0200 |
parents | 80a3433ace91 |
children | 0e01f9182e16 |
rev | line source |
---|---|
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
1 /* |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
2 * Copyright (c) 2010-2011 TMate Software Ltd |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
3 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
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:
52
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:
52
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:
52
diff
changeset
|
7 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
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:
52
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:
52
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:
52
diff
changeset
|
11 * GNU General Public License for more details. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
12 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
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:
52
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 |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 */ |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
17 package org.tmatesoft.hg.internal; |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
18 |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
19 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
20 import static org.tmatesoft.hg.repo.HgRepository.TIP; |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
21 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
22 import java.io.File; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
23 import java.io.IOException; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
24 import java.util.ArrayList; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
25 import java.util.LinkedList; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
26 import java.util.List; |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
27 |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
28 import org.tmatesoft.hg.core.HgBadStateException; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
29 import org.tmatesoft.hg.core.Nodeid; |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
30 import org.tmatesoft.hg.repo.HgRepository; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
31 |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
32 |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
33 /** |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
34 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations), |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
35 * or numerous RevlogStream with separate representation of the underlying data (cached, lazy ChunkStream)? |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
36 * |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
37 * @see http://mercurial.selenic.com/wiki/Revlog |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
38 * @see http://mercurial.selenic.com/wiki/RevlogNG |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
39 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
40 * @author Artem Tikhomirov |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
52
diff
changeset
|
41 * @author TMate Software Ltd. |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
42 */ |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
43 public class RevlogStream { |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
44 |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
45 /* |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
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)) |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
47 * |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
48 * long[] in fact (there are 8-bytes field in the revlog) |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
49 * However, (a) DataAccess currently doesn't operate with long seek/length |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
50 * and, of greater significance, (b) files with inlined data are designated for smaller files, |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
51 * guess, about 130 Kb, and offset there won't ever break int capacity |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
52 */ |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
53 private int[] indexRecordOffset; |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
54 private int[] baseRevisions; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
55 private boolean inline = false; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
56 private final File indexFile; |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
57 private final DataAccessProvider dataAccess; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
58 |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
59 // if we need anything else from HgRepo, might replace DAP parameter with HgRepo and query it for DAP. |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
60 public RevlogStream(DataAccessProvider dap, File indexFile) { |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
61 this.dataAccess = dap; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
62 this.indexFile = indexFile; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
63 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
64 |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
65 /*package*/ DataAccess getIndexStream() { |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
66 return dataAccess.create(indexFile); |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
67 } |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
68 |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
69 /*package*/ DataAccess getDataStream() { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
70 final String indexName = indexFile.getName(); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
71 File dataFile = new File(indexFile.getParentFile(), indexName.substring(0, indexName.length() - 1) + "d"); |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
72 return dataAccess.create(dataFile); |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
73 } |
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
74 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
75 public int revisionCount() { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
76 initOutline(); |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
77 return baseRevisions.length; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
78 } |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
79 |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
80 public int dataLength(int revision) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
81 // XXX in fact, use of iterate() instead of this implementation may be quite reasonable. |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
82 // |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
83 final int indexSize = revisionCount(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
84 DataAccess daIndex = getIndexStream(); // XXX may supply a hint that I'll need really few bytes of data (although at some offset) |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
85 if (revision == TIP) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
86 revision = indexSize - 1; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
87 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
88 try { |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
89 int recordOffset = getIndexOffsetInt(revision); |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
90 daIndex.seek(recordOffset + 12); // 6+2+4 |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
91 int actualLen = daIndex.readInt(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
92 return actualLen; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
93 } catch (IOException ex) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
94 ex.printStackTrace(); // log error. FIXME better handling |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
95 throw new IllegalStateException(ex); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
96 } finally { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
97 daIndex.done(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
98 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
99 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
100 |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
101 public byte[] nodeid(int revision) { |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
102 final int indexSize = revisionCount(); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
103 if (revision == TIP) { |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
104 revision = indexSize - 1; |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
105 } |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
106 if (revision < 0 || revision >= indexSize) { |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
107 throw new IllegalArgumentException(Integer.toString(revision)); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
108 } |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
109 DataAccess daIndex = getIndexStream(); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
110 try { |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
111 int recordOffset = getIndexOffsetInt(revision); |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
112 daIndex.seek(recordOffset + 32); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
113 byte[] rv = new byte[20]; |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
114 daIndex.readBytes(rv, 0, 20); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
115 return rv; |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
116 } catch (IOException ex) { |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
117 ex.printStackTrace(); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
118 throw new IllegalStateException(); |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
119 } finally { |
88
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
120 daIndex.done(); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
121 } |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
122 } |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
123 |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
124 public int linkRevision(int revision) { |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
125 final int last = revisionCount() - 1; |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
126 if (revision == TIP) { |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
127 revision = last; |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
128 } |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
129 if (revision < 0 || revision > last) { |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
130 throw new IllegalArgumentException(Integer.toString(revision)); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
131 } |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
132 DataAccess daIndex = getIndexStream(); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
133 try { |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
134 int recordOffset = getIndexOffsetInt(revision); |
88
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
135 daIndex.seek(recordOffset + 20); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
136 int linkRev = daIndex.readInt(); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
137 return linkRev; |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
138 } catch (IOException ex) { |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
139 ex.printStackTrace(); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
140 throw new IllegalStateException(); |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
141 } finally { |
61eedab3eb3e
Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
142 daIndex.done(); |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
143 } |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
144 } |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
145 |
49
26e3eeaa3962
branch and user filtering for log operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
44
diff
changeset
|
146 // Perhaps, RevlogStream should be limited to use of plain int revisions for access, |
26e3eeaa3962
branch and user filtering for log operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
44
diff
changeset
|
147 // while Nodeids should be kept on the level up, in Revlog. Guess, Revlog better keep |
26e3eeaa3962
branch and user filtering for log operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
44
diff
changeset
|
148 // map of nodeids, and once this comes true, we may get rid of this method. |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
149 // Unlike its counterpart, {@link Revlog#getLocalRevisionNumber()}, doesn't fail with exception if node not found, |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
150 /** |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
151 * @return integer in [0..revisionCount()) or {@link HgRepository#BAD_REVISION} if not found |
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
152 */ |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
153 public int findLocalRevisionNumber(Nodeid nodeid) { |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
154 // XXX this one may be implemented with iterate() once there's mechanism to stop iterations |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
155 final int indexSize = revisionCount(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
156 DataAccess daIndex = getIndexStream(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
157 try { |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
158 byte[] nodeidBuf = new byte[20]; |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
159 for (int i = 0; i < indexSize; i++) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
160 daIndex.skip(8); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
161 int compressedLen = daIndex.readInt(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
162 daIndex.skip(20); |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
163 daIndex.readBytes(nodeidBuf, 0, 20); |
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
164 if (nodeid.equalsTo(nodeidBuf)) { |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
165 return i; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
166 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
167 daIndex.skip(inline ? 12 + compressedLen : 12); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
168 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
169 } catch (IOException ex) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
170 ex.printStackTrace(); // log error. FIXME better handling |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
171 throw new IllegalStateException(ex); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
172 } finally { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
173 daIndex.done(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
174 } |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
77
diff
changeset
|
175 return BAD_REVISION; |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
176 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
177 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
178 |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
179 private final int REVLOGV1_RECORD_SIZE = 64; |
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
180 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
181 // should be possible to use TIP, ALL, or -1, -2, -n notation of Hg |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
182 // ? boolean needsNodeid |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
183 public void iterate(int start, int end, boolean needData, Inspector inspector) { |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
184 initOutline(); |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
185 final int indexSize = revisionCount(); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
186 if (indexSize == 0) { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
187 return; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
188 } |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
189 if (end == TIP) { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
190 end = indexSize - 1; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
191 } |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
192 if (start == TIP) { |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
193 start = indexSize - 1; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
194 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
195 if (start < 0 || start >= indexSize) { |
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>
diff
changeset
|
196 throw new IllegalArgumentException(String.format("Bad left range boundary %d in [0..%d]", start, indexSize-1)); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
197 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
198 if (end < start || end >= indexSize) { |
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>
diff
changeset
|
199 throw new IllegalArgumentException(String.format("Bad right range boundary %d in [0..%d]", end, indexSize-1)); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
200 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
201 // XXX may cache [start .. end] from index with a single read (pre-read) |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
202 |
242
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
203 ReaderN1 r = new ReaderN1(needData, inspector); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
204 try { |
242
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
205 r.start(end - start + 1); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
206 r.range(start, end); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
207 } catch (IOException ex) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
208 throw new HgBadStateException(ex); // FIXME need better handling |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
209 } finally { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
210 r.finish(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
211 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
212 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
213 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
214 /** |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
215 * Effective alternative to {@link #iterate(int, int, boolean, Inspector) batch read}, when only few selected |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
216 * revisions are of interest. |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
217 * @param sortedRevisions revisions to walk, in ascending order. |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
218 * @param needData whether inspector needs access to header only |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
219 * @param inspector callback to process entries |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
220 */ |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
221 public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
222 final int indexSize = revisionCount(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
223 if (indexSize == 0 || sortedRevisions.length == 0) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
224 return; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
225 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
226 if (sortedRevisions[0] > indexSize || sortedRevisions[sortedRevisions.length - 1] > indexSize) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
227 throw new IllegalArgumentException(String.format("Can't iterate [%d, %d] in range [0..%d]", sortedRevisions[0], sortedRevisions[sortedRevisions.length - 1], indexSize)); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
228 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
229 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
230 ReaderN1 r = new ReaderN1(needData, inspector); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
231 try { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
232 r.start(sortedRevisions.length); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
233 for (int i = 0; i < sortedRevisions.length; ) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
234 int x = i; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
235 i++; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
236 while (i < sortedRevisions.length) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
237 if (sortedRevisions[i] == sortedRevisions[i-1] + 1) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
238 i++; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
239 } else { |
217
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
202
diff
changeset
|
240 break; |
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
202
diff
changeset
|
241 } |
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
202
diff
changeset
|
242 } |
242
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
243 // commitRevisions[x..i-1] are sequential |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
244 if (!r.range(sortedRevisions[x], sortedRevisions[i-1])) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
245 return; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
246 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
247 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
248 } catch (IOException ex) { |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
249 throw new HgBadStateException(ex); // FIXME need better handling |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
250 } finally { |
242
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
251 r.finish(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
252 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
253 } |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
254 |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
255 private int getBaseRevision(int revision) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
256 return baseRevisions[revision]; |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
257 } |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
258 |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
259 /** |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
260 * @return offset of the revision's record in the index (.i) stream |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
261 */ |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
262 private int getIndexOffsetInt(int revision) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
263 return inline ? indexRecordOffset[revision] : revision * REVLOGV1_RECORD_SIZE; |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
264 } |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
265 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
266 private void initOutline() { |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
267 if (baseRevisions != null && baseRevisions.length > 0) { |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
268 return; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
269 } |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
270 ArrayList<Integer> resBases = new ArrayList<Integer>(); |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
271 ArrayList<Integer> resOffsets = new ArrayList<Integer>(); |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
272 DataAccess da = getIndexStream(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
273 try { |
202
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
198
diff
changeset
|
274 if (da.isEmpty()) { |
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
198
diff
changeset
|
275 // do not fail with exception if stream is empty, it's likely intentional |
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
198
diff
changeset
|
276 baseRevisions = new int[0]; |
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
198
diff
changeset
|
277 return; |
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
198
diff
changeset
|
278 } |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
279 int versionField = da.readInt(); |
170
71ddbf8603e8
Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
280 da.readInt(); // just to skip next 4 bytes of offset + flags |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
281 final int INLINEDATA = 1 << 16; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
282 inline = (versionField & INLINEDATA) != 0; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
283 long offset = 0; // first offset is always 0, thus Hg uses it for other purposes |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
284 while(true) { |
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
285 int compressedLen = da.readInt(); |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
286 // 8+4 = 12 bytes total read here |
49
26e3eeaa3962
branch and user filtering for log operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
44
diff
changeset
|
287 @SuppressWarnings("unused") |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
288 int actualLen = da.readInt(); |
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
289 int baseRevision = da.readInt(); |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
290 // 12 + 8 = 20 bytes read here |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
291 // int linkRevision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
292 // int parent1Revision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
293 // int parent2Revision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
294 // byte[] nodeid = new byte[32]; |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
295 resBases.add(baseRevision); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
296 if (inline) { |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
297 int o = (int) offset; |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
298 if (o != offset) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
299 // just in case, can't happen, ever, unless HG (or some other bad tool) produces index file |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
300 // with inlined data of size greater than 2 Gb. |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
301 throw new HgBadStateException("Data too big, offset didn't fit to sizeof(int)"); |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
302 } |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
303 resOffsets.add(o + REVLOGV1_RECORD_SIZE * resOffsets.size()); |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
304 da.skip(3*4 + 32 + compressedLen); // Check: 44 (skip) + 20 (read) = 64 (total RevlogNG record size) |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
305 } else { |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
306 da.skip(3*4 + 32); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
307 } |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
308 if (da.isEmpty()) { |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
309 // fine, done then |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
310 baseRevisions = toArray(resBases); |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
311 if (inline) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
312 indexRecordOffset = toArray(resOffsets); |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
313 } |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
314 break; |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
315 } else { |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
316 // start reading next record |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
317 long l = da.readLong(); |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
318 offset = l >>> 16; |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
319 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
320 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
321 } catch (IOException ex) { |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
322 ex.printStackTrace(); // log error |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
323 // too bad, no outline then, but don't fail with NPE |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
324 baseRevisions = new int[0]; |
9
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
325 } finally { |
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
6
diff
changeset
|
326 da.done(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
327 } |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
328 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
329 |
242
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
330 /** |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
331 * operation with single file open/close and multiple diverse reads. |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
332 * XXX initOutline might need similar extraction to keen N1 format knowledge |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
333 */ |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
334 class ReaderN1 { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
335 private final Inspector inspector; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
336 private final boolean needData; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
337 private DataAccess daIndex = null, daData = null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
338 private Lifecycle.BasicCallback cb = null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
339 private int lastRevisionRead = BAD_REVISION; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
340 private DataAccess lastUserData; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
341 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
342 public ReaderN1(boolean needData, Inspector insp) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
343 assert insp != null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
344 this.needData = needData; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
345 inspector = insp; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
346 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
347 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
348 public void start(int totalWork) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
349 daIndex = getIndexStream(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
350 if (needData && !inline) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
351 daData = getDataStream(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
352 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
353 if (inspector instanceof Lifecycle) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
354 cb = new Lifecycle.BasicCallback(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
355 ((Lifecycle) inspector).start(totalWork, cb, cb); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
356 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
357 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
358 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
359 public void finish() { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
360 if (lastUserData != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
361 lastUserData.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
362 lastUserData = null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
363 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
364 if (inspector instanceof Lifecycle) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
365 ((Lifecycle) inspector).finish(cb); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
366 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
367 daIndex.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
368 if (daData != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
369 daData.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
370 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
371 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
372 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
373 public boolean range(int start, int end) throws IOException { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
374 // System.out.printf("RevlogStream.ReaderN1.range(): [%d, %d]\n", start, end); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
375 byte[] nodeidBuf = new byte[20]; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
376 int i; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
377 boolean extraReadsToBaseRev = false; // to indicate we read revision prior to start. XXX not sure can't do without |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
378 // it (i.e. replace with i >= start) |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
379 if (needData && (i = getBaseRevision(start)) < start) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
380 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
381 // doesn't make sense to reuse if lastRevisionRead == start (too much to change in the cycle below). |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
382 if (lastRevisionRead != BAD_REVISION && i <= lastRevisionRead && lastRevisionRead < start) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
383 i = lastRevisionRead + 1; // start with first not-yet-read revision |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
384 extraReadsToBaseRev = i < start; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
385 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
386 if (lastUserData != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
387 lastUserData.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
388 lastUserData = null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
389 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
390 extraReadsToBaseRev = true; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
391 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
392 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
393 // don't need to clean lastUserData as it's always null when !needData |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
394 i = start; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
395 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
396 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
397 daIndex.seek(getIndexOffsetInt(i)); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
398 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
399 for (; i <= end; i++ ) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
400 if (inline && needData) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
401 // inspector reading data (though FilterDataAccess) may have affected index position |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
402 daIndex.seek(getIndexOffsetInt(i)); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
403 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
404 long l = daIndex.readLong(); // 0 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
405 long offset = i == 0 ? 0 : (l >>> 16); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
406 @SuppressWarnings("unused") |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
407 int flags = (int) (l & 0X0FFFF); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
408 int compressedLen = daIndex.readInt(); // +8 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
409 int actualLen = daIndex.readInt(); // +12 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
410 int baseRevision = daIndex.readInt(); // +16 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
411 int linkRevision = daIndex.readInt(); // +20 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
412 int parent1Revision = daIndex.readInt(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
413 int parent2Revision = daIndex.readInt(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
414 // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
415 daIndex.readBytes(nodeidBuf, 0, 20); // +32 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
416 daIndex.skip(12); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
417 DataAccess userDataAccess = null; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
418 if (needData) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
419 int streamOffset; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
420 DataAccess streamDataAccess; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
421 if (inline) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
422 streamDataAccess = daIndex; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
423 streamOffset = getIndexOffsetInt(i) + REVLOGV1_RECORD_SIZE; // don't need to do seek as it's actual position in the index stream |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
424 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
425 streamOffset = (int) offset; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
426 streamDataAccess = daData; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
427 daData.seek(streamOffset); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
428 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
429 final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
430 if (streamDataAccess.isEmpty()) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
431 userDataAccess = new DataAccess(); // empty |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
432 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
433 final byte firstByte = streamDataAccess.readByte(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
434 if (firstByte == 0x78 /* 'x' */) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
435 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, patchToPrevious ? -1 : actualLen); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
436 } else if (firstByte == 0x75 /* 'u' */) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
437 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
438 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
439 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0' |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
440 // but I don't see reason not to return data as is |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
441 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
442 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
443 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
444 // XXX |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
445 if (patchToPrevious) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
446 // this is a patch |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
447 LinkedList<PatchRecord> patches = new LinkedList<PatchRecord>(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
448 while (!userDataAccess.isEmpty()) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
449 PatchRecord pr = PatchRecord.read(userDataAccess); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
450 // System.out.printf("PatchRecord:%d %d %d\n", pr.start, pr.end, pr.len); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
451 patches.add(pr); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
452 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
453 userDataAccess.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
454 // |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
455 byte[] userData = apply(lastUserData, actualLen, patches); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
456 userDataAccess = new ByteArrayDataAccess(userData); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
457 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
458 } else { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
459 if (inline) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
460 daIndex.skip(compressedLen); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
461 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
462 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
463 if (!extraReadsToBaseRev || i >= start) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
464 inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, userDataAccess); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
465 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
466 if (cb != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
467 if (cb.isStopped()) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
468 return false; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
469 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
470 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
471 if (userDataAccess != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
472 userDataAccess.reset(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
473 if (lastUserData != null) { |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
474 lastUserData.done(); |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
475 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
476 lastUserData = userDataAccess; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
477 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
478 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
479 lastRevisionRead = end; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
480 return true; |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
481 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
482 } |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
483 |
ad6a046943be
Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
223
diff
changeset
|
484 |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
485 private static int[] toArray(List<Integer> l) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
486 int[] rv = new int[l.size()]; |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
487 for (int i = 0; i < rv.length; i++) { |
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
488 rv[i] = l.get(i); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
489 } |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
490 return rv; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
491 } |
198
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
170
diff
changeset
|
492 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
493 |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
494 // mpatch.c : apply() |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
495 // FIXME need to implement patch merge (fold, combine, gather and discard from aforementioned mpatch.[c|py]), also see Revlog and Mercurial PDF |
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>
diff
changeset
|
496 public/*for HgBundle; until moved to better place*/static byte[] apply(DataAccess baseRevisionContent, int outcomeLen, List<PatchRecord> patch) throws IOException { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
497 int last = 0, destIndex = 0; |
43
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
498 if (outcomeLen == -1) { |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
499 outcomeLen = baseRevisionContent.length(); |
43
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
500 for (PatchRecord pr : patch) { |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
501 outcomeLen += pr.start - last + pr.len; |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
502 last = pr.end; |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
503 } |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
504 outcomeLen -= last; |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
505 last = 0; |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
506 } |
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
507 byte[] rv = new byte[outcomeLen]; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
508 for (PatchRecord pr : patch) { |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
509 baseRevisionContent.seek(last); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
510 baseRevisionContent.readBytes(rv, destIndex, pr.start-last); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
511 destIndex += pr.start - last; |
43
1b26247d7367
Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
37
diff
changeset
|
512 System.arraycopy(pr.data, 0, rv, destIndex, pr.data.length); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
513 destIndex += pr.data.length; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
514 last = pr.end; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
515 } |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
516 baseRevisionContent.seek(last); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
517 baseRevisionContent.readBytes(rv, destIndex, (int) (baseRevisionContent.length() - last)); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
518 return rv; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
519 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
520 |
35
6061aa826a9e
Complete parsing of the bundle format
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
33
diff
changeset
|
521 // @see http://mercurial.selenic.com/wiki/BundleFormat, in Changelog group description |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
522 public static class PatchRecord { |
52
30bd38978846
brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
523 /* |
30bd38978846
brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
524 Given there are pr1 and pr2: |
30bd38978846
brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
525 pr1.start to pr1.end will be replaced with pr's data (of pr1.len) |
30bd38978846
brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
526 pr1.end to pr2.start gets copied from base |
30bd38978846
brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
49
diff
changeset
|
527 */ |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
528 public int start, end, len; |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
529 public byte[] data; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
530 |
36
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
531 // TODO consider PatchRecord that only records data position (absolute in data source), and acquires data as needed |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
532 private PatchRecord(int p1, int p2, int length, byte[] src) { |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
533 start = p1; |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
534 end = p2; |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
535 len = length; |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
536 data = src; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
537 } |
36
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
538 |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
539 /*package-local*/ static PatchRecord read(byte[] data, int offset) { |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
540 final int x = offset; // shorthand |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
541 int p1 = ((data[x] & 0xFF)<< 24) | ((data[x+1] & 0xFF) << 16) | ((data[x+2] & 0xFF) << 8) | (data[x+3] & 0xFF); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
542 int p2 = ((data[x+4] & 0xFF) << 24) | ((data[x+5] & 0xFF) << 16) | ((data[x+6] & 0xFF) << 8) | (data[x+7] & 0xFF); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
543 int len = ((data[x+8] & 0xFF) << 24) | ((data[x+9] & 0xFF) << 16) | ((data[x+10] & 0xFF) << 8) | (data[x+11] & 0xFF); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
544 byte[] dataCopy = new byte[len]; |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
545 System.arraycopy(data, x+12, dataCopy, 0, len); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
546 return new PatchRecord(p1, p2, len, dataCopy); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
547 } |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
548 |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
549 public /*for HgBundle*/ static PatchRecord read(DataAccess da) throws IOException { |
36
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
550 int p1 = da.readInt(); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
551 int p2 = da.readInt(); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
552 int len = da.readInt(); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
553 byte[] src = new byte[len]; |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
554 da.readBytes(src, 0, len); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
555 return new PatchRecord(p1, p2, len, src); |
205f9b59b400
Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
35
diff
changeset
|
556 } |
77
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
557 } |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
558 |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
559 // 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 |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
560 // instantly - e.g. calculate hash, or comparing two revisions |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
561 public interface Inspector { |
c677e1593919
Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
562 // XXX boolean retVal to indicate whether to continue? |
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>
diff
changeset
|
563 // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) |
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>
diff
changeset
|
564 // implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment |
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>
diff
changeset
|
565 void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
566 } |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
567 } |