annotate src/org/tmatesoft/hg/internal/RevlogStream.java @ 215:41a778e3fd31

Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 17 May 2011 00:56:54 +0200
parents 706bcc7cfee4
children e39cf474ef94
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>
parents: 53 102
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>
parents: 53 102
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
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
203 DataAccess daIndex = null, daData = null;
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
204 daIndex = getIndexStream();
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
205 if (needData && !inline) {
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
206 daData = getDataStream();
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
207 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
208 try {
24
d4fdd1845b3f Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 22
diff changeset
209 byte[] nodeidBuf = new byte[20];
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
210 DataAccess lastUserData = null;
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
211 int i;
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
212 boolean extraReadsToBaseRev = false;
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
213 if (needData && getBaseRevision(start) < start) {
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
214 i = getBaseRevision(start);
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
215 extraReadsToBaseRev = true;
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
216 } else {
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
217 i = start;
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
218 }
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
219
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
220 daIndex.seek(getIndexOffsetInt(i));
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
221 for (; i <= end; i++ ) {
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
222 if (inline && needData) {
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
223 // inspector reading data (though FilterDataAccess) may have affected index position
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
224 daIndex.seek(getIndexOffsetInt(i));
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
225 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 53 102
diff changeset
226 long l = daIndex.readLong(); // 0
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
227 long offset = i == 0 ? 0 : (l >>> 16);
49
26e3eeaa3962 branch and user filtering for log operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 44
diff changeset
228 @SuppressWarnings("unused")
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
229 int flags = (int) (l & 0X0FFFF);
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 80
diff changeset
230 int compressedLen = daIndex.readInt(); // +8
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 80
diff changeset
231 int actualLen = daIndex.readInt(); // +12
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 80
diff changeset
232 int baseRevision = daIndex.readInt(); // +16
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 80
diff changeset
233 int linkRevision = daIndex.readInt(); // +20
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
234 int parent1Revision = daIndex.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
235 int parent2Revision = daIndex.readInt();
24
d4fdd1845b3f Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 22
diff changeset
236 // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 80
diff changeset
237 daIndex.readBytes(nodeidBuf, 0, 20); // +32
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
238 daIndex.skip(12);
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
239 DataAccess userDataAccess = null;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
240 if (needData) {
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
241 final byte firstByte;
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
242 int streamOffset;
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
243 DataAccess streamDataAccess;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
244 if (inline) {
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
245 streamDataAccess = daIndex;
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
246 streamOffset = getIndexOffsetInt(i) + REVLOGV1_RECORD_SIZE; // don't need to do seek as it's actual position in the index stream
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
247 } else {
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
248 streamOffset = (int) offset;
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
249 streamDataAccess = daData;
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
250 daData.seek(streamOffset);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
251 }
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
252 final boolean patchToPrevious = baseRevision != i; // the only way I found to tell if it's a patch
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
253 firstByte = streamDataAccess.readByte();
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
254 if (firstByte == 0x78 /* 'x' */) {
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
255 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, patchToPrevious ? -1 : actualLen);
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
256 } else if (firstByte == 0x75 /* 'u' */) {
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
257 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
258 } else {
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
259 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0'
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
260 // but I don't see reason not to return data as is
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
261 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
262 }
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
263 // XXX
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
264 if (patchToPrevious) {
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
265 // this is a patch
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
266 LinkedList<PatchRecord> patches = new LinkedList<PatchRecord>();
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
267 while (!userDataAccess.isEmpty()) {
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
268 PatchRecord pr = PatchRecord.read(userDataAccess);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 53 102
diff changeset
269 // System.out.printf("PatchRecord:%d %d %d\n", pr.start, pr.end, pr.len);
36
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
270 patches.add(pr);
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
271 }
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
272 userDataAccess.done();
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
273 //
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
274 byte[] userData = apply(lastUserData, actualLen, patches);
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
275 userDataAccess = new ByteArrayDataAccess(userData);
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
276 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
277 } else {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
278 if (inline) {
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 daIndex.skip(compressedLen);
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
280 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
281 }
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
282 if (!extraReadsToBaseRev || i >= start) {
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
283 inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, userDataAccess);
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 4
diff changeset
284 }
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
285 if (userDataAccess != null) {
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
286 userDataAccess.reset();
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
287 if (lastUserData != null) {
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
288 lastUserData.done();
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
289 }
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
290 lastUserData = userDataAccess;
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
291 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
292 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
293 } 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
294 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
295 } finally {
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
296 daIndex.done();
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
297 if (daData != null) {
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
298 daData.done();
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
299 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
300 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
301 }
198
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 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
304 return baseRevisions[revision];
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
305 }
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
306
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
307 /**
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
308 * @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
309 */
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
310 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
311 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
312 }
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
313
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
314 private void initOutline() {
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
315 if (baseRevisions != null && baseRevisions.length > 0) {
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
316 return;
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
317 }
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
318 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
319 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
320 DataAccess da = getIndexStream();
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
321 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
322 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
323 // 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
324 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
325 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
326 }
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
327 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
328 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
329 final int INLINEDATA = 1 << 16;
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
330 inline = (versionField & INLINEDATA) != 0;
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
331 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
332 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
333 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
334 // 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
335 @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
336 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
337 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
338 // 12 + 8 = 20 bytes read here
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
339 // int linkRevision = di.readInt();
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
340 // int parent1Revision = di.readInt();
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
341 // int parent2Revision = di.readInt();
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
342 // 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
343 resBases.add(baseRevision);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
344 if (inline) {
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
345 int o = (int) offset;
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
346 if (o != offset) {
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
347 // 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
348 // 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
349 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
350 }
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
351 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
352 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
353 } 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
354 da.skip(3*4 + 32);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
355 }
10
382cfe9463db Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 9
diff changeset
356 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
357 // fine, done then
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
358 baseRevisions = toArray(resBases);
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
359 if (inline) {
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
360 indexRecordOffset = toArray(resOffsets);
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
361 }
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
362 break;
10
382cfe9463db Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 9
diff changeset
363 } else {
382cfe9463db Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 9
diff changeset
364 // 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
365 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
366 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
367 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
368 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
369 } 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
370 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
371 // 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
372 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
373 } 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
374 da.done();
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
375 }
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
376 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
377
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
378 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
379 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
380 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
381 rv[i] = l.get(i);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
382 }
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
383 return rv;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 0
diff changeset
384 }
198
33a7d76f067b Performance optimization: reduce memory to keep revlog cached info
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 170
diff changeset
385
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
386
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
387 // mpatch.c : apply()
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
388 // FIXME need to implement patch merge (fold, combine, gather and discard from aforementioned mpatch.[c|py]), also see Revlog and Mercurial PDF
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 53 102
diff changeset
389 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
390 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
391 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
392 outcomeLen = baseRevisionContent.length();
43
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
393 for (PatchRecord pr : patch) {
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
394 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
395 last = pr.end;
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
396 }
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
397 outcomeLen -= last;
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
398 last = 0;
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
399 }
1b26247d7367 Calculate result length of the patch operarion, when unknown
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
400 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
401 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
402 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
403 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
404 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
405 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
406 destIndex += pr.data.length;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
407 last = pr.end;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
408 }
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
409 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
410 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
411 return rv;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
412 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
413
35
6061aa826a9e Complete parsing of the bundle format
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 33
diff changeset
414 // @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
415 public static class PatchRecord {
52
30bd38978846 brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
416 /*
30bd38978846 brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
417 Given there are pr1 and pr2:
30bd38978846 brief explanation of patch record
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
418 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
419 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
420 */
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
421 public int start, end, len;
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
422 public byte[] data;
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
423
36
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
424 // 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
425 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
426 start = p1;
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
427 end = p2;
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
428 len = length;
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
429 data = src;
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
430 }
36
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
431
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
432 /*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
433 final int x = offset; // shorthand
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
434 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
435 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
436 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
437 byte[] dataCopy = new byte[len];
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
438 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
439 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
440 }
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
441
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
442 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
443 int p1 = da.readInt();
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
444 int p2 = da.readInt();
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
445 int len = da.readInt();
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
446 byte[] src = new byte[len];
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
447 da.readBytes(src, 0, len);
205f9b59b400 Strip parsing logic out from console frontend
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 35
diff changeset
448 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
449 }
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
450 }
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
451
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
452 // FIXME byte[] data might be too expensive, for few usecases it may be better to have intermediate Access object (when we don't need full data
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
453 // 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
454 public interface Inspector {
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
455 // 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>
parents: 53 102
diff changeset
456 // 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>
parents: 53 102
diff changeset
457 // 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>
parents: 53 102
diff changeset
458 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
459 }
0
dbd663faec1f Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
460 }