comparison mercurial/revlog.py @ 47038:724db234b790

revlog: code for `revlogv0` in its own module This code is mostly unused compatiblity code. Yet it take a prohiminent place in the `revlog.py` module. That module is already quite big, so we move all that code in a dedicated module. Differential Revision: https://phab.mercurial-scm.org/D10511
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 08 Apr 2021 00:34:16 +0200
parents d57386e5c80e
children a407fe56d6e8
comparison
equal deleted inserted replaced
47037:d57386e5c80e 47038:724db234b790
34 from .i18n import _ 34 from .i18n import _
35 from .pycompat import getattr 35 from .pycompat import getattr
36 from .revlogutils.constants import ( 36 from .revlogutils.constants import (
37 FLAG_GENERALDELTA, 37 FLAG_GENERALDELTA,
38 FLAG_INLINE_DATA, 38 FLAG_INLINE_DATA,
39 INDEX_ENTRY_V0,
40 INDEX_HEADER, 39 INDEX_HEADER,
41 REVLOGV0, 40 REVLOGV0,
42 REVLOGV1, 41 REVLOGV1,
43 REVLOGV1_FLAGS, 42 REVLOGV1_FLAGS,
44 REVLOGV2, 43 REVLOGV2,
74 ) 73 )
75 from .revlogutils import ( 74 from .revlogutils import (
76 deltas as deltautil, 75 deltas as deltautil,
77 flagutil, 76 flagutil,
78 nodemap as nodemaputil, 77 nodemap as nodemaputil,
78 revlogv0,
79 sidedata as sidedatautil, 79 sidedata as sidedatautil,
80 ) 80 )
81 from .utils import ( 81 from .utils import (
82 storageutil, 82 storageutil,
83 stringutil, 83 stringutil,
134 ellipsiswriteprocessor, 134 ellipsiswriteprocessor,
135 ellipsisrawprocessor, 135 ellipsisrawprocessor,
136 ) 136 )
137 137
138 138
139 def getoffset(q):
140 return int(q >> 16)
141
142
143 def gettype(q):
144 return int(q & 0xFFFF)
145
146
147 def offset_type(offset, type): 139 def offset_type(offset, type):
148 if (type & ~flagutil.REVIDX_KNOWN_FLAGS) != 0: 140 if (type & ~flagutil.REVIDX_KNOWN_FLAGS) != 0:
149 raise ValueError(b'unknown revlog index flags') 141 raise ValueError(b'unknown revlog index flags')
150 return int(int(offset) << 16 | type) 142 return int(int(offset) << 16 | type)
151 143
210 @attr.s(frozen=True) 202 @attr.s(frozen=True)
211 class revlogproblem(object): 203 class revlogproblem(object):
212 warning = attr.ib(default=None) 204 warning = attr.ib(default=None)
213 error = attr.ib(default=None) 205 error = attr.ib(default=None)
214 node = attr.ib(default=None) 206 node = attr.ib(default=None)
215
216
217 class revlogoldindex(list):
218 entry_size = INDEX_ENTRY_V0.size
219
220 @property
221 def nodemap(self):
222 msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]"
223 util.nouideprecwarn(msg, b'5.3', stacklevel=2)
224 return self._nodemap
225
226 @util.propertycache
227 def _nodemap(self):
228 nodemap = nodemaputil.NodeMap({sha1nodeconstants.nullid: nullrev})
229 for r in range(0, len(self)):
230 n = self[r][7]
231 nodemap[n] = r
232 return nodemap
233
234 def has_node(self, node):
235 """return True if the node exist in the index"""
236 return node in self._nodemap
237
238 def rev(self, node):
239 """return a revision for a node
240
241 If the node is unknown, raise a RevlogError"""
242 return self._nodemap[node]
243
244 def get_rev(self, node):
245 """return a revision for a node
246
247 If the node is unknown, return None"""
248 return self._nodemap.get(node)
249
250 def append(self, tup):
251 self._nodemap[tup[7]] = len(self)
252 super(revlogoldindex, self).append(tup)
253
254 def __delitem__(self, i):
255 if not isinstance(i, slice) or not i.stop == -1 or i.step is not None:
256 raise ValueError(b"deleting slices only supports a:-1 with step 1")
257 for r in pycompat.xrange(i.start, len(self)):
258 del self._nodemap[self[r][7]]
259 super(revlogoldindex, self).__delitem__(i)
260
261 def clearcaches(self):
262 self.__dict__.pop('_nodemap', None)
263
264 def __getitem__(self, i):
265 if i == -1:
266 return (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid)
267 return list.__getitem__(self, i)
268
269 def entry_binary(self, rev):
270 """return the raw binary string representing a revision"""
271 entry = self[rev]
272 if gettype(entry[0]):
273 raise error.RevlogError(
274 _(b'index entry flags need revlog version 1')
275 )
276 e2 = (
277 getoffset(entry[0]),
278 entry[1],
279 entry[3],
280 entry[4],
281 self[entry[5]][7],
282 self[entry[6]][7],
283 entry[7],
284 )
285 return INDEX_ENTRY_V0.pack(*e2)
286
287 def pack_header(self, header):
288 """Pack header information in binary"""
289 return b''
290
291
292 def parse_index_v0(data, inline):
293 s = INDEX_ENTRY_V0.size
294 index = []
295 nodemap = nodemaputil.NodeMap({sha1nodeconstants.nullid: nullrev})
296 n = off = 0
297 l = len(data)
298 while off + s <= l:
299 cur = data[off : off + s]
300 off += s
301 e = INDEX_ENTRY_V0.unpack(cur)
302 # transform to revlogv1 format
303 e2 = (
304 offset_type(e[0], 0),
305 e[1],
306 -1,
307 e[2],
308 e[3],
309 nodemap.get(e[4], nullrev),
310 nodemap.get(e[5], nullrev),
311 e[6],
312 )
313 index.append(e2)
314 nodemap[e[6]] = n
315 n += 1
316
317 index = revlogoldindex(index)
318 return index, None
319 207
320 208
321 def parse_index_v1(data, inline): 209 def parse_index_v1(data, inline):
322 # call the C implementation to parse the index data 210 # call the C implementation to parse the index data
323 index, cache = parsers.parse_index2(data, inline) 211 index, cache = parsers.parse_index2(data, inline)
619 else: 507 else:
620 use_rust_index = self.opener.options.get(b'rust.index') 508 use_rust_index = self.opener.options.get(b'rust.index')
621 509
622 self._parse_index = parse_index_v1 510 self._parse_index = parse_index_v1
623 if self.version == REVLOGV0: 511 if self.version == REVLOGV0:
624 self._parse_index = parse_index_v0 512 self._parse_index = revlogv0.parse_index_v0
625 elif fmt == REVLOGV2: 513 elif fmt == REVLOGV2:
626 self._parse_index = parse_index_v2 514 self._parse_index = parse_index_v2
627 elif devel_nodemap: 515 elif devel_nodemap:
628 self._parse_index = parse_index_v1_nodemap 516 self._parse_index = parse_index_v1_nodemap
629 elif use_rust_index: 517 elif use_rust_index: