Mercurial > jhg
annotate src/com/tmate/hgkit/ll/RevlogStream.java @ 30:de7217a0aa4d
Look up changes in the local repo that are not in the remote
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 11 Jan 2011 04:49:06 +0100 |
parents | d4fdd1845b3f |
children | 565ce0835674 |
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 /* |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
2 * Copyright (c) 2010, 2011 Artem Tikhomirov |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
3 */ |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
4 package com.tmate.hgkit.ll; |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
5 |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
6 import static com.tmate.hgkit.ll.HgRepository.TIP; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
7 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
8 import java.io.File; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
9 import java.io.IOException; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
10 import java.util.ArrayList; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
11 import java.util.Collections; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
12 import java.util.LinkedList; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
13 import java.util.List; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
14 import java.util.zip.DataFormatException; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
15 import java.util.zip.Inflater; |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
17 import com.tmate.hgkit.fs.DataAccess; |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
18 import com.tmate.hgkit.fs.DataAccessProvider; |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
19 |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
20 /** |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
21 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations), |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
22 * or numerous RevlogStream with separate representation of the underlaying data (cached, lazy ChunkStream)? |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
23 * @author artem |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
24 * @see http://mercurial.selenic.com/wiki/Revlog |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
25 * @see http://mercurial.selenic.com/wiki/RevlogNG |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
26 */ |
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
27 public class RevlogStream { |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
28 |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
29 private List<IndexEntry> index; // indexed access highly needed |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
30 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
|
31 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
|
32 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
|
33 |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
34 // if we need anything else from HgRepo, might replace DAP parameter with HgRepo and query it for DAP. |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
35 RevlogStream(DataAccessProvider dap, File indexFile) { |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
36 this.dataAccess = dap; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
37 this.indexFile = indexFile; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
38 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
39 |
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
|
40 /*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
|
41 return dataAccess.create(indexFile); |
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 |
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
|
44 /*package*/ DataAccess getDataStream() { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
45 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
|
46 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
|
47 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
|
48 } |
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
|
49 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
50 public int revisionCount() { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
51 initOutline(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
52 return index.size(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
53 } |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
54 |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
55 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
|
56 // 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
|
57 // |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
58 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
|
59 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
|
60 if (revision == TIP) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
61 revision = indexSize - 1; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
62 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
63 try { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
64 int recordOffset = inline ? (int) index.get(revision).offset : revision * REVLOGV1_RECORD_SIZE; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
65 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
|
66 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
|
67 return actualLen; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
68 } catch (IOException ex) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
69 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
|
70 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
|
71 } finally { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
72 daIndex.done(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
73 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
74 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
75 |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
76 public int findLocalRevisionNumber(Nodeid nodeid) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
77 // 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
|
78 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
|
79 DataAccess daIndex = getIndexStream(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
80 try { |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
81 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
|
82 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
|
83 daIndex.skip(8); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
84 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
|
85 daIndex.skip(20); |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
86 daIndex.readBytes(nodeidBuf, 0, 20); |
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
87 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
|
88 return i; |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
89 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
90 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
|
91 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
92 } catch (IOException ex) { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
93 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
|
94 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
|
95 } finally { |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
96 daIndex.done(); |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
97 } |
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
98 throw new IllegalArgumentException(String.format("%s doesn't represent a revision of %s", nodeid.toString(), indexFile.getName() /*XXX HgDataFile.getPath might be more suitable here*/)); |
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 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
101 |
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
|
102 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
|
103 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
104 // 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
|
105 // ? boolean needsNodeid |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
106 public void iterate(int start, int end, boolean needData, Revlog.Inspector inspector) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
107 initOutline(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
108 final int indexSize = index.size(); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
109 if (indexSize == 0) { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
110 return; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
111 } |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
112 if (end == TIP) { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
113 end = indexSize - 1; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
114 } |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
115 if (start == TIP) { |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
116 start = indexSize - 1; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
117 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
118 if (start < 0 || start >= indexSize) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
119 throw new IllegalArgumentException("Bad left range boundary " + start); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
120 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
121 if (end < start || end >= indexSize) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
122 throw new IllegalArgumentException("Bad right range boundary " + end); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
123 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
124 // 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
|
125 |
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
|
126 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
|
127 daIndex = getIndexStream(); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
128 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
|
129 daData = getDataStream(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
130 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
131 try { |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
132 byte[] nodeidBuf = new byte[20]; |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
133 byte[] lastData = null; |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
134 int i; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
135 boolean extraReadsToBaseRev = false; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
136 if (needData && index.get(start).baseRevision < start) { |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
137 i = index.get(start).baseRevision; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
138 extraReadsToBaseRev = true; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
139 } else { |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
140 i = start; |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
141 } |
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
|
142 |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
143 daIndex.seek(inline ? (int) index.get(i).offset : i * REVLOGV1_RECORD_SIZE); |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
144 for (; i <= end; i++ ) { |
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
|
145 long l = daIndex.readLong(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
146 long offset = l >>> 16; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
147 int flags = (int) (l & 0X0FFFF); |
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
|
148 int compressedLen = 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
|
149 int actualLen = 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
|
150 int baseRevision = 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
|
151 int linkRevision = 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
|
152 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
|
153 int parent2Revision = daIndex.readInt(); |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
154 // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty |
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
155 daIndex.readBytes(nodeidBuf, 0, 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
|
156 daIndex.skip(12); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
157 byte[] data = null; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
158 if (needData) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
159 byte[] dataBuf = new byte[compressedLen]; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
160 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
|
161 daIndex.readBytes(dataBuf, 0, compressedLen); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
162 } 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
|
163 daData.seek(index.get(i).offset); |
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
|
164 daData.readBytes(dataBuf, 0, compressedLen); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
165 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
166 if (dataBuf[0] == 0x78 /* 'x' */) { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
167 try { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
168 Inflater zlib = new Inflater(); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
169 zlib.setInput(dataBuf, 0, compressedLen); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
170 byte[] result = new byte[actualLen*2]; // FIXME need to use zlib.finished() instead |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
171 int resultLen = zlib.inflate(result); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
172 zlib.end(); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
173 data = new byte[resultLen]; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
174 System.arraycopy(result, 0, data, 0, resultLen); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
175 } catch (DataFormatException ex) { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
176 ex.printStackTrace(); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
177 data = new byte[0]; // FIXME need better failure strategy |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
178 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
179 } else if (dataBuf[0] == 0x75 /* 'u' */) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
180 data = new byte[dataBuf.length - 1]; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
181 System.arraycopy(dataBuf, 1, data, 0, data.length); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
182 } else { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
183 // 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
|
184 // but I don't see reason not to return data as is |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
185 data = dataBuf; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
186 } |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
187 // XXX |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
188 if (baseRevision != i) { // XXX not sure if this is the right way to detect a patch |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
189 // this is a patch |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
190 LinkedList<PatchRecord> patches = new LinkedList<PatchRecord>(); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
191 int patchElementIndex = 0; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
192 do { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
193 final int x = patchElementIndex; // shorthand |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
194 int p1 = ((data[x] & 0xFF)<< 24) | ((data[x+1] & 0xFF) << 16) | ((data[x+2] & 0xFF) << 8) | (data[x+3] & 0xFF); |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
195 int p2 = ((data[x+4] & 0xFF) << 24) | ((data[x+5] & 0xFF) << 16) | ((data[x+6] & 0xFF) << 8) | (data[x+7] & 0xFF); |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
196 int len = ((data[x+8] & 0xFF) << 24) | ((data[x+9] & 0xFF) << 16) | ((data[x+10] & 0xFF) << 8) | (data[x+11] & 0xFF); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
197 patchElementIndex += 12 + len; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
198 patches.add(new PatchRecord(p1, p2, len, data, x+12)); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
199 } while (patchElementIndex < data.length); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
200 // |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
201 byte[] baseRevContent = lastData; |
6
5abe5af181bd
Ant script to build commands and run sample
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
5
diff
changeset
|
202 data = apply(baseRevContent, actualLen, patches); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
203 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
204 } else { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
205 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
|
206 daIndex.skip(compressedLen); |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
207 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
208 } |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
209 if (!extraReadsToBaseRev || i >= start) { |
24
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
22
diff
changeset
|
210 inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, data); |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
211 } |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
212 lastData = data; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
213 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
214 } catch (IOException ex) { |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
215 throw new IllegalStateException(ex); // FIXME need better handling |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
216 } 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
|
217 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
|
218 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
|
219 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
|
220 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
221 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
222 } |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
223 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
224 private void initOutline() { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
225 if (index != null && !index.isEmpty()) { |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
226 return; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
227 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
228 ArrayList<IndexEntry> res = new ArrayList<IndexEntry>(); |
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
|
229 DataAccess da = getIndexStream(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
230 try { |
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
|
231 int versionField = 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
|
232 da.readInt(); // just to skip next 2 bytes of offset + flags |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
233 final int INLINEDATA = 1 << 16; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
234 inline = (versionField & INLINEDATA) != 0; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
235 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
|
236 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
|
237 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
|
238 // 8+4 = 12 bytes total read here |
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
|
239 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
|
240 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
|
241 // 12 + 8 = 20 bytes read here |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
242 // int linkRevision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
243 // int parent1Revision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
244 // int parent2Revision = di.readInt(); |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
245 // byte[] nodeid = new byte[32]; |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
246 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
|
247 res.add(new IndexEntry(offset + REVLOGV1_RECORD_SIZE * res.size(), baseRevision)); |
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
|
248 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
|
249 } else { |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
250 res.add(new IndexEntry(offset, baseRevision)); |
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
|
251 da.skip(3*4 + 32); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
252 } |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
253 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
|
254 // fine, done then |
22
603806cd2dc6
Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
10
diff
changeset
|
255 res.trimToSize(); |
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
|
256 index = res; |
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
|
257 break; |
10
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
258 } else { |
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
9
diff
changeset
|
259 // 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
|
260 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
|
261 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
|
262 } |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
263 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
264 } 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
|
265 ex.printStackTrace(); // log error |
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
|
266 // too bad, no outline then. |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
267 index = Collections.emptyList(); |
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
|
268 } 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
|
269 da.done(); |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
270 } |
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
|
271 |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
272 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
273 |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
274 |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
275 // perhaps, package-local or protected, if anyone else from low-level needs them |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
276 // XXX think over if we should keep offset in case of separate data file - we read the field anyway. Perhaps, distinct entry classes for Inline and non-inline indexes? |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
277 private static class IndexEntry { |
4
aa1912c70b36
Fix offset issue for inline revlogs. Commandline processing.
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
3
diff
changeset
|
278 public final long offset; // for separate .i and .d - copy of index record entry, for inline index - actual offset of the record in the .i file (record entry + revision * record size)) |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
279 //public final int length; // data past fixed record (need to decide whether including header size or not), and whether length is of compressed data or not |
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
280 public final int baseRevision; |
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 public IndexEntry(long o, int baseRev) { |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
283 offset = o; |
5
fc265ddeab26
File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
4
diff
changeset
|
284 baseRevision = baseRev; |
2
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
285 } |
08db726a0fb7
Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
0
diff
changeset
|
286 } |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
287 |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
288 // mpatch.c : apply() |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
289 // FIXME need to implement patch merge (fold, combine, gather and discard from aforementioned mpatch.[c|py]), also see Revlog and Mercurial PDF |
6
5abe5af181bd
Ant script to build commands and run sample
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
5
diff
changeset
|
290 private static byte[] apply(byte[] baseRevisionContent, int outcomeLen, List<PatchRecord> patch) { |
5abe5af181bd
Ant script to build commands and run sample
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
5
diff
changeset
|
291 byte[] tempBuf = new byte[outcomeLen]; // XXX |
3
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
292 int last = 0, destIndex = 0; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
293 for (PatchRecord pr : patch) { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
294 System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, pr.start-last); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
295 destIndex += pr.start - last; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
296 System.arraycopy(pr.data, 0, tempBuf, destIndex, pr.data.length); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
297 destIndex += pr.data.length; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
298 last = pr.end; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
299 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
300 System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, baseRevisionContent.length - last); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
301 destIndex += baseRevisionContent.length - last; // total length |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
302 byte[] rv = new byte[destIndex]; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
303 System.arraycopy(tempBuf, 0, rv, 0, destIndex); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
304 return rv; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
305 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
306 |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
307 static class PatchRecord { // copy of struct frag from mpatch.c |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
308 int start, end, len; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
309 byte[] data; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
310 |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
311 public PatchRecord(int p1, int p2, int len, byte[] src, int srcOffset) { |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
312 start = p1; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
313 end = p2; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
314 this.len = len; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
315 data = new byte[len]; |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
316 System.arraycopy(src, srcOffset, data, 0, len); |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
317 } |
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
2
diff
changeset
|
318 } |
0
dbd663faec1f
Basic changelog parsing
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
319 } |