##// END OF EJS Templates
help: clarify contents of revlog index...
Gregory Szorc -
r30499:22d05b53 default
parent child Browse files
Show More
@@ -1,198 +1,199 b''
1 Revision logs - or *revlogs* - are an append only data structure for
1 Revision logs - or *revlogs* - are an append only data structure for
2 storing discrete entries, or *revisions*. They are the primary storage
2 storing discrete entries, or *revisions*. They are the primary storage
3 mechanism of repository data.
3 mechanism of repository data.
4
4
5 Revlogs effectively model a directed acyclic graph (DAG). Each node
5 Revlogs effectively model a directed acyclic graph (DAG). Each node
6 has edges to 1 or 2 *parent* nodes. Each node contains metadata and
6 has edges to 1 or 2 *parent* nodes. Each node contains metadata and
7 the raw value for that node.
7 the raw value for that node.
8
8
9 Revlogs consist of entries which have metadata and revision data.
9 Revlogs consist of entries which have metadata and revision data.
10 Metadata includes the hash of the revision's content, sizes, and
10 Metadata includes the hash of the revision's content, sizes, and
11 links to its *parent* entries. The collective metadata is referred
11 links to its *parent* entries. The collective metadata is referred
12 to as the *index* and the revision data is the *data*.
12 to as the *index* and the revision data is the *data*.
13
13
14 Revision data is stored as a series of compressed deltas against previous
14 Revision data is stored as a series of compressed deltas against previous
15 revisions.
15 revisions.
16
16
17 Revlogs are written in an append-only fashion. We never need to rewrite
17 Revlogs are written in an append-only fashion. We never need to rewrite
18 a file to insert nor do we need to remove data. Rolling back in-progress
18 a file to insert nor do we need to remove data. Rolling back in-progress
19 writes can be performed by truncating files. Read locks can be avoided
19 writes can be performed by truncating files. Read locks can be avoided
20 using simple techniques. This means that references to other data in
20 using simple techniques. This means that references to other data in
21 the same revlog *always* refer to a previous entry.
21 the same revlog *always* refer to a previous entry.
22
22
23 Revlogs can be modeled as 0-indexed arrays. The first revision is
23 Revlogs can be modeled as 0-indexed arrays. The first revision is
24 revision #0 and the second is revision #1. The revision -1 is typically
24 revision #0 and the second is revision #1. The revision -1 is typically
25 used to mean *does not exist* or *not defined*.
25 used to mean *does not exist* or *not defined*.
26
26
27 File Format
27 File Format
28 ===========
28 ===========
29
29
30 A revlog begins with a 32-bit big endian integer holding version info
30 A revlog begins with a 32-bit big endian integer holding version info
31 and feature flags. This integer is shared with the first revision
31 and feature flags. This integer is shared with the first revision
32 entry.
32 entry.
33
33
34 This integer is logically divided into 2 16-bit shorts. The least
34 This integer is logically divided into 2 16-bit shorts. The least
35 significant half of the integer is the format/version short. The other
35 significant half of the integer is the format/version short. The other
36 short holds feature flags that dictate behavior of the revlog.
36 short holds feature flags that dictate behavior of the revlog.
37
37
38 Only 1 bit of the format/version short is currently used. Remaining
38 Only 1 bit of the format/version short is currently used. Remaining
39 bits are reserved for future use.
39 bits are reserved for future use.
40
40
41 The following values for the format/version short are defined:
41 The following values for the format/version short are defined:
42
42
43 0
43 0
44 The original revlog version.
44 The original revlog version.
45 1
45 1
46 RevlogNG (*next generation*). It replaced version 0 when it was
46 RevlogNG (*next generation*). It replaced version 0 when it was
47 implemented in 2006.
47 implemented in 2006.
48
48
49 The feature flags short consists of bit flags. Where 0 is the least
49 The feature flags short consists of bit flags. Where 0 is the least
50 significant bit, the following bit offsets define flags:
50 significant bit, the following bit offsets define flags:
51
51
52 0
52 0
53 Store revision data inline.
53 Store revision data inline.
54 1
54 1
55 Generaldelta encoding.
55 Generaldelta encoding.
56
56
57 2-15
57 2-15
58 Reserved for future use.
58 Reserved for future use.
59
59
60 The following header values are common:
60 The following header values are common:
61
61
62 00 00 00 01
62 00 00 00 01
63 RevlogNG
63 RevlogNG
64 00 01 00 01
64 00 01 00 01
65 RevlogNG + inline
65 RevlogNG + inline
66 00 02 00 01
66 00 02 00 01
67 RevlogNG + generaldelta
67 RevlogNG + generaldelta
68 00 03 00 01
68 00 03 00 01
69 RevlogNG + inline + generaldelta
69 RevlogNG + inline + generaldelta
70
70
71 Following the 32-bit header is the remainder of the first index entry.
71 Following the 32-bit header is the remainder of the first index entry.
72 Following that are remaining *index* data. Inlined revision data is
72 Following that are remaining *index* data. Inlined revision data is
73 possibly located between index entries. More on this layout is described
73 possibly located between index entries. More on this layout is described
74 below.
74 below.
75
75
76 RevlogNG Format
76 RevlogNG Format
77 ===============
77 ===============
78
78
79 RevlogNG (version 1) begins with an index describing the revisions in
79 RevlogNG (version 1) begins with an index describing the revisions in
80 the revlog. If the ``inline`` flag is set, revision data is stored inline,
80 the revlog. If the ``inline`` flag is set, revision data is stored inline,
81 or between index entries (as opposed to in a separate container).
81 or between index entries (as opposed to in a separate container).
82
82
83 Each index entry is 64 bytes. The byte layout of each entry is as
83 Each index entry is 64 bytes. The byte layout of each entry is as
84 follows, with byte 0 being the first byte (all data stored as big endian):
84 follows, with byte 0 being the first byte (all data stored as big endian):
85
85
86 0-3 (4 bytes) (rev 0 only)
86 0-3 (4 bytes) (rev 0 only)
87 Revlog header
87 Revlog header
88 0-5 (6 bytes)
88 0-5 (6 bytes)
89 Absolute offset of revision data from beginning of revlog.
89 Absolute offset of revision data from beginning of revlog.
90 6-7 (2 bytes)
90 6-7 (2 bytes)
91 Bit flags impacting revision behavior.
91 Bit flags impacting revision behavior.
92 8-11 (4 bytes)
92 8-11 (4 bytes)
93 Compressed length of revision data / chunk as stored in revlog.
93 Compressed length of revision data / chunk as stored in revlog.
94 12-15 (4 bytes)
94 12-15 (4 bytes)
95 Uncompressed length of revision data / chunk.
95 Uncompressed length of revision data. This is the size of the full
96 revision data, not the size of the chunk post decompression.
96 16-19 (4 bytes)
97 16-19 (4 bytes)
97 Base or previous revision this revision's delta was produced against.
98 Base or previous revision this revision's delta was produced against.
98 -1 means this revision holds full text (as opposed to a delta).
99 -1 means this revision holds full text (as opposed to a delta).
99 For generaldelta repos, this is the previous revision in the delta
100 For generaldelta repos, this is the previous revision in the delta
100 chain. For non-generaldelta repos, this is the base or first
101 chain. For non-generaldelta repos, this is the base or first
101 revision in the delta chain.
102 revision in the delta chain.
102 20-23 (4 bytes)
103 20-23 (4 bytes)
103 A revision this revision is *linked* to. This allows a revision in
104 A revision this revision is *linked* to. This allows a revision in
104 one revlog to be forever associated with a revision in another
105 one revlog to be forever associated with a revision in another
105 revlog. For example, a file's revlog may point to the changelog
106 revlog. For example, a file's revlog may point to the changelog
106 revision that introduced it.
107 revision that introduced it.
107 24-27 (4 bytes)
108 24-27 (4 bytes)
108 Revision of 1st parent. -1 indicates no parent.
109 Revision of 1st parent. -1 indicates no parent.
109 28-31 (4 bytes)
110 28-31 (4 bytes)
110 Revision of 2nd parent. -1 indicates no 2nd parent.
111 Revision of 2nd parent. -1 indicates no 2nd parent.
111 32-63 (32 bytes)
112 32-63 (32 bytes)
112 Hash of revision's full text. Currently, SHA-1 is used and only
113 Hash of revision's full text. Currently, SHA-1 is used and only
113 the first 20 bytes of this field are used. The rest of the bytes
114 the first 20 bytes of this field are used. The rest of the bytes
114 are ignored and should be stored as \0.
115 are ignored and should be stored as \0.
115
116
116 If inline revision data is being stored, the compressed revision data
117 If inline revision data is being stored, the compressed revision data
117 (of length from bytes offset 8-11 from the index entry) immediately
118 (of length from bytes offset 8-11 from the index entry) immediately
118 follows the index entry. There is no header on the revision data. There
119 follows the index entry. There is no header on the revision data. There
119 is no padding between it and the index entries before and after.
120 is no padding between it and the index entries before and after.
120
121
121 If revision data is not inline, then raw revision data is stored in a
122 If revision data is not inline, then raw revision data is stored in a
122 separate byte container. The offsets from bytes 0-5 and the compressed
123 separate byte container. The offsets from bytes 0-5 and the compressed
123 length from bytes 8-11 define how to access this data.
124 length from bytes 8-11 define how to access this data.
124
125
125 The first 4 bytes of the revlog are shared between the revlog header
126 The first 4 bytes of the revlog are shared between the revlog header
126 and the 6 byte absolute offset field from the first revlog entry.
127 and the 6 byte absolute offset field from the first revlog entry.
127
128
128 Delta Chains
129 Delta Chains
129 ============
130 ============
130
131
131 Revision data is encoded as a chain of *chunks*. Each chain begins with
132 Revision data is encoded as a chain of *chunks*. Each chain begins with
132 the compressed original full text for that revision. Each subsequent
133 the compressed original full text for that revision. Each subsequent
133 *chunk* is a *delta* against the previous revision. We therefore call
134 *chunk* is a *delta* against the previous revision. We therefore call
134 these chains of chunks/deltas *delta chains*.
135 these chains of chunks/deltas *delta chains*.
135
136
136 The full text for a revision is reconstructed by loading the original
137 The full text for a revision is reconstructed by loading the original
137 full text for the base revision of a *delta chain* and then applying
138 full text for the base revision of a *delta chain* and then applying
138 *deltas* until the target revision is reconstructed.
139 *deltas* until the target revision is reconstructed.
139
140
140 *Delta chains* are limited in length so lookup time is bound. They are
141 *Delta chains* are limited in length so lookup time is bound. They are
141 limited to ~2x the length of the revision's data. The linear distance
142 limited to ~2x the length of the revision's data. The linear distance
142 between the base chunk and the final chunk is also limited so the
143 between the base chunk and the final chunk is also limited so the
143 amount of read I/O to load all chunks in the delta chain is bound.
144 amount of read I/O to load all chunks in the delta chain is bound.
144
145
145 Deltas and delta chains are either computed against the previous
146 Deltas and delta chains are either computed against the previous
146 revision in the revlog or another revision (almost certainly one of
147 revision in the revlog or another revision (almost certainly one of
147 the parents of the revision). Historically, deltas were computed against
148 the parents of the revision). Historically, deltas were computed against
148 the previous revision. The *generaldelta* revlog feature flag (enabled
149 the previous revision. The *generaldelta* revlog feature flag (enabled
149 by default in Mercurial 3.7) activates the mode where deltas are
150 by default in Mercurial 3.7) activates the mode where deltas are
150 computed against an arbitrary revision (almost certainly a parent revision).
151 computed against an arbitrary revision (almost certainly a parent revision).
151
152
152 File Storage
153 File Storage
153 ============
154 ============
154
155
155 Revlogs logically consist of an index (metadata of entries) and
156 Revlogs logically consist of an index (metadata of entries) and
156 revision data. This data may be stored together in a single file or in
157 revision data. This data may be stored together in a single file or in
157 separate files. The mechanism used is indicated by the ``inline`` feature
158 separate files. The mechanism used is indicated by the ``inline`` feature
158 flag on the revlog.
159 flag on the revlog.
159
160
160 Mercurial's behavior is to use inline storage until a revlog reaches a
161 Mercurial's behavior is to use inline storage until a revlog reaches a
161 certain size, at which point it will be converted to non-inline. The
162 certain size, at which point it will be converted to non-inline. The
162 reason there is a size limit on inline storage is to establish an upper
163 reason there is a size limit on inline storage is to establish an upper
163 bound on how much data must be read to load the index. It would be a waste
164 bound on how much data must be read to load the index. It would be a waste
164 to read tens or hundreds of extra megabytes of data just to access the
165 to read tens or hundreds of extra megabytes of data just to access the
165 index data.
166 index data.
166
167
167 The actual layout of revlog files on disk is governed by the repository's
168 The actual layout of revlog files on disk is governed by the repository's
168 *store format*. Typically, a ``.i`` file represents the index revlog
169 *store format*. Typically, a ``.i`` file represents the index revlog
169 (possibly containing inline data) and a ``.d`` file holds the revision data.
170 (possibly containing inline data) and a ``.d`` file holds the revision data.
170
171
171 Revision Entries
172 Revision Entries
172 ================
173 ================
173
174
174 Revision entries consist of an optional 1 byte header followed by an
175 Revision entries consist of an optional 1 byte header followed by an
175 encoding of the revision data. The headers are as follows:
176 encoding of the revision data. The headers are as follows:
176
177
177 \0 (0x00)
178 \0 (0x00)
178 Revision data is the entirety of the entry, including this header.
179 Revision data is the entirety of the entry, including this header.
179 u (0x75)
180 u (0x75)
180 Raw revision data follows.
181 Raw revision data follows.
181 x (0x78)
182 x (0x78)
182 zlib (RFC 1950) data.
183 zlib (RFC 1950) data.
183
184
184 The 0x78 value is actually the first byte of the zlib header (CMF byte).
185 The 0x78 value is actually the first byte of the zlib header (CMF byte).
185
186
186 Hash Computation
187 Hash Computation
187 ================
188 ================
188
189
189 The hash of the revision is stored in the index and is used both as a primary
190 The hash of the revision is stored in the index and is used both as a primary
190 key and for data integrity verification.
191 key and for data integrity verification.
191
192
192 Currently, SHA-1 is the only supported hashing algorithm. To obtain the SHA-1
193 Currently, SHA-1 is the only supported hashing algorithm. To obtain the SHA-1
193 hash of a revision:
194 hash of a revision:
194
195
195 1. Hash the parent nodes
196 1. Hash the parent nodes
196 2. Hash the fulltext of the revision
197 2. Hash the fulltext of the revision
197
198
198 The 20 byte node ids of the parents are fed into the hasher in ascending order.
199 The 20 byte node ids of the parents are fed into the hasher in ascending order.
General Comments 0
You need to be logged in to leave comments. Login now