##// END OF EJS Templates
revlog: use a "radix" to address revlog...
marmoute -
r47921:8d3c2f9d default
parent child Browse files
Show More
@@ -36,10 +36,15 b" def printb(data, end=b'\\n'):"
36
36
37
37
38 for f in sys.argv[1:]:
38 for f in sys.argv[1:]:
39 localf = encoding.strtolocal(f)
40 if not localf.endswith(b'.i'):
41 print("file:", f, file=sys.stderr)
42 print(" invalida filename", file=sys.stderr)
43
39 r = revlog.revlog(
44 r = revlog.revlog(
40 binopen,
45 binopen,
41 target=(revlog_constants.KIND_OTHER, b'dump-revlog'),
46 target=(revlog_constants.KIND_OTHER, b'dump-revlog'),
42 indexfile=encoding.strtolocal(f),
47 radix=localf[:-2],
43 )
48 )
44 print("file:", f)
49 print("file:", f)
45 for i in r:
50 for i in r:
@@ -1826,7 +1826,10 b' def perfnodelookup(ui, repo, rev, **opts'
1826 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1826 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1827 n = scmutil.revsingle(repo, rev).node()
1827 n = scmutil.revsingle(repo, rev).node()
1828
1828
1829 cl = revlog(getsvfs(repo), indexfile=b"00changelog.i")
1829 try:
1830 cl = revlog(getsvfs(repo), radix=b"00changelog")
1831 except TypeError:
1832 cl = revlog(getsvfs(repo), indexfile=b"00changelog.i")
1830
1833
1831 def d():
1834 def d():
1832 cl.rev(n)
1835 cl.rev(n)
@@ -2610,6 +2613,7 b' def perfrevlogindex(ui, repo, file_=None'
2610
2613
2611 opener = getattr(rl, 'opener') # trick linter
2614 opener = getattr(rl, 'opener') # trick linter
2612 # compat with hg <= 5.8
2615 # compat with hg <= 5.8
2616 radix = getattr(rl, 'radix', None)
2613 indexfile = getattr(rl, '_indexfile', None)
2617 indexfile = getattr(rl, '_indexfile', None)
2614 if indexfile is None:
2618 if indexfile is None:
2615 # compatibility with <= hg-5.8
2619 # compatibility with <= hg-5.8
@@ -2641,7 +2645,11 b' def perfrevlogindex(ui, repo, file_=None'
2641 allnodesrev = list(reversed(allnodes))
2645 allnodesrev = list(reversed(allnodes))
2642
2646
2643 def constructor():
2647 def constructor():
2644 revlog(opener, indexfile=indexfile)
2648 if radix is not None:
2649 revlog(opener, radix=radix)
2650 else:
2651 # hg <= 5.8
2652 revlog(opener, indexfile=indexfile)
2645
2653
2646 def read():
2654 def read():
2647 with opener(indexfile) as fh:
2655 with opener(indexfile) as fh:
@@ -3043,8 +3051,9 b' def _temprevlog(ui, orig, truncaterev):'
3043
3051
3044 datafile = getattr(orig, '_datafile', getattr(orig, 'datafile'))
3052 datafile = getattr(orig, '_datafile', getattr(orig, 'datafile'))
3045 origdatapath = orig.opener.join(datafile)
3053 origdatapath = orig.opener.join(datafile)
3046 indexname = 'revlog.i'
3054 radix = b'revlog'
3047 dataname = 'revlog.d'
3055 indexname = b'revlog.i'
3056 dataname = b'revlog.d'
3048
3057
3049 tmpdir = tempfile.mkdtemp(prefix='tmp-hgperf-')
3058 tmpdir = tempfile.mkdtemp(prefix='tmp-hgperf-')
3050 try:
3059 try:
@@ -3069,9 +3078,12 b' def _temprevlog(ui, orig, truncaterev):'
3069 vfs = vfsmod.vfs(tmpdir)
3078 vfs = vfsmod.vfs(tmpdir)
3070 vfs.options = getattr(orig.opener, 'options', None)
3079 vfs.options = getattr(orig.opener, 'options', None)
3071
3080
3072 dest = revlog(
3081 try:
3073 vfs, indexfile=indexname, datafile=dataname, **revlogkwargs
3082 dest = revlog(vfs, radix=radix, **revlogkwargs)
3074 )
3083 except TypeError:
3084 dest = revlog(
3085 vfs, indexfile=indexname, datafile=dataname, **revlogkwargs
3086 )
3075 if dest._inline:
3087 if dest._inline:
3076 raise error.Abort('not supporting inline revlog (yet)')
3088 raise error.Abort('not supporting inline revlog (yet)')
3077 # make sure internals are initialized
3089 # make sure internals are initialized
@@ -32,10 +32,11 b' while True:'
32 break
32 break
33 if l.startswith("file:"):
33 if l.startswith("file:"):
34 f = encoding.strtolocal(l[6:-1])
34 f = encoding.strtolocal(l[6:-1])
35 assert f.endswith(b'.i')
35 r = revlog.revlog(
36 r = revlog.revlog(
36 opener,
37 opener,
37 target=(revlog_constants.KIND_OTHER, b'undump-revlog'),
38 target=(revlog_constants.KIND_OTHER, b'undump-revlog'),
38 indexfile=f,
39 radix=f[:-2],
39 )
40 )
40 procutil.stdout.write(b'%s\n' % f)
41 procutil.stdout.write(b'%s\n' % f)
41 elif l.startswith("node:"):
42 elif l.startswith("node:"):
@@ -281,7 +281,7 b' class manifestrevlogstore(object):'
281 self._store = repo.store
281 self._store = repo.store
282 self._svfs = repo.svfs
282 self._svfs = repo.svfs
283 self._revlogs = dict()
283 self._revlogs = dict()
284 self._cl = revlog.revlog(self._svfs, indexfile=b'00changelog.i')
284 self._cl = revlog.revlog(self._svfs, radix=b'00changelog.i')
285 self._repackstartlinkrev = 0
285 self._repackstartlinkrev = 0
286
286
287 def get(self, name, node):
287 def get(self, name, node):
@@ -341,10 +341,10 b' class manifestrevlogstore(object):'
341 def _revlog(self, name):
341 def _revlog(self, name):
342 rl = self._revlogs.get(name)
342 rl = self._revlogs.get(name)
343 if rl is None:
343 if rl is None:
344 revlogname = b'00manifesttree.i'
344 revlogname = b'00manifesttree'
345 if name != b'':
345 if name != b'':
346 revlogname = b'meta/%s/00manifest.i' % name
346 revlogname = b'meta/%s/00manifest' % name
347 rl = revlog.revlog(self._svfs, indexfile=revlogname)
347 rl = revlog.revlog(self._svfs, radix=revlogname)
348 self._revlogs[name] = rl
348 self._revlogs[name] = rl
349 return rl
349 return rl
350
350
@@ -365,7 +365,7 b' class manifestrevlogstore(object):'
365 if options and options.get(constants.OPTION_PACKSONLY):
365 if options and options.get(constants.OPTION_PACKSONLY):
366 return
366 return
367 treename = b''
367 treename = b''
368 rl = revlog.revlog(self._svfs, indexfile=b'00manifesttree.i')
368 rl = revlog.revlog(self._svfs, radix=b'00manifesttree')
369 startlinkrev = self._repackstartlinkrev
369 startlinkrev = self._repackstartlinkrev
370 endlinkrev = self._repackendlinkrev
370 endlinkrev = self._repackendlinkrev
371 for rev in pycompat.xrange(len(rl) - 1, -1, -1):
371 for rev in pycompat.xrange(len(rl) - 1, -1, -1):
@@ -382,9 +382,9 b' class manifestrevlogstore(object):'
382 if path[:5] != b'meta/' or path[-2:] != b'.i':
382 if path[:5] != b'meta/' or path[-2:] != b'.i':
383 continue
383 continue
384
384
385 treename = path[5 : -len(b'/00manifest.i')]
385 treename = path[5 : -len(b'/00manifest')]
386
386
387 rl = revlog.revlog(self._svfs, indexfile=path)
387 rl = revlog.revlog(self._svfs, indexfile=path[:-2])
388 for rev in pycompat.xrange(len(rl) - 1, -1, -1):
388 for rev in pycompat.xrange(len(rl) - 1, -1, -1):
389 linkrev = rl.linkrev(rev)
389 linkrev = rl.linkrev(rev)
390 if linkrev < startlinkrev:
390 if linkrev < startlinkrev:
@@ -52,7 +52,7 b' from .revlogutils import ('
52
52
53
53
54 class bundlerevlog(revlog.revlog):
54 class bundlerevlog(revlog.revlog):
55 def __init__(self, opener, target, indexfile, cgunpacker, linkmapper):
55 def __init__(self, opener, target, radix, cgunpacker, linkmapper):
56 # How it works:
56 # How it works:
57 # To retrieve a revision, we need to know the offset of the revision in
57 # To retrieve a revision, we need to know the offset of the revision in
58 # the bundle (an unbundle object). We store this offset in the index
58 # the bundle (an unbundle object). We store this offset in the index
@@ -61,7 +61,7 b' class bundlerevlog(revlog.revlog):'
61 # To differentiate a rev in the bundle from a rev in the revlog, we
61 # To differentiate a rev in the bundle from a rev in the revlog, we
62 # check revision against repotiprev.
62 # check revision against repotiprev.
63 opener = vfsmod.readonlyvfs(opener)
63 opener = vfsmod.readonlyvfs(opener)
64 revlog.revlog.__init__(self, opener, target=target, indexfile=indexfile)
64 revlog.revlog.__init__(self, opener, target=target, radix=radix)
65 self.bundle = cgunpacker
65 self.bundle = cgunpacker
66 n = len(self)
66 n = len(self)
67 self.repotiprev = n - 1
67 self.repotiprev = n - 1
@@ -180,7 +180,7 b' class bundlechangelog(bundlerevlog, chan'
180 self,
180 self,
181 opener,
181 opener,
182 (revlog_constants.KIND_CHANGELOG, None),
182 (revlog_constants.KIND_CHANGELOG, None),
183 self._indexfile,
183 self.radix,
184 cgunpacker,
184 cgunpacker,
185 linkmapper,
185 linkmapper,
186 )
186 )
@@ -201,7 +201,7 b' class bundlemanifest(bundlerevlog, manif'
201 self,
201 self,
202 opener,
202 opener,
203 (revlog_constants.KIND_MANIFESTLOG, dir),
203 (revlog_constants.KIND_MANIFESTLOG, dir),
204 self._revlog._indexfile,
204 self._revlog.radix,
205 cgunpacker,
205 cgunpacker,
206 linkmapper,
206 linkmapper,
207 )
207 )
@@ -233,7 +233,7 b' class bundlefilelog(filelog.filelog):'
233 opener,
233 opener,
234 # XXX should use the unencoded path
234 # XXX should use the unencoded path
235 target=(revlog_constants.KIND_FILELOG, path),
235 target=(revlog_constants.KIND_FILELOG, path),
236 indexfile=self._revlog._indexfile,
236 radix=self._revlog.radix,
237 cgunpacker=cgunpacker,
237 cgunpacker=cgunpacker,
238 linkmapper=linkmapper,
238 linkmapper=linkmapper,
239 )
239 )
@@ -396,20 +396,17 b' class changelog(revlog.revlog):'
396 the documentation there.
396 the documentation there.
397 """
397 """
398
398
399 indexfile = b'00changelog.i'
400 if trypending and opener.exists(b'00changelog.i.a'):
399 if trypending and opener.exists(b'00changelog.i.a'):
401 postfix = b'a'
400 postfix = b'a'
402 else:
401 else:
403 postfix = None
402 postfix = None
404
403
405 datafile = b'00changelog.d'
406 revlog.revlog.__init__(
404 revlog.revlog.__init__(
407 self,
405 self,
408 opener,
406 opener,
409 target=(revlog_constants.KIND_CHANGELOG, None),
407 target=(revlog_constants.KIND_CHANGELOG, None),
408 radix=b'00changelog',
410 postfix=postfix,
409 postfix=postfix,
411 indexfile=indexfile,
412 datafile=datafile,
413 checkambig=True,
410 checkambig=True,
414 mmaplargeindex=True,
411 mmaplargeindex=True,
415 persistentnodemap=opener.options.get(b'persistent-nodemap', False),
412 persistentnodemap=opener.options.get(b'persistent-nodemap', False),
@@ -1437,7 +1437,7 b' def openstorage(repo, cmd, file_, opts, '
1437 r = revlog.revlog(
1437 r = revlog.revlog(
1438 vfsmod.vfs(encoding.getcwd(), audit=False),
1438 vfsmod.vfs(encoding.getcwd(), audit=False),
1439 target=target,
1439 target=target,
1440 indexfile=file_[:-2] + b".i",
1440 radix=file_[:-2],
1441 )
1441 )
1442 return r
1442 return r
1443
1443
@@ -30,7 +30,7 b' class filelog(object):'
30 opener,
30 opener,
31 # XXX should use the unencoded path
31 # XXX should use the unencoded path
32 target=(revlog_constants.KIND_FILELOG, path),
32 target=(revlog_constants.KIND_FILELOG, path),
33 indexfile=b'/'.join((b'data', path + b'.i')),
33 radix=b'/'.join((b'data', path)),
34 censorable=True,
34 censorable=True,
35 )
35 )
36 # Full name of the user visible file, relative to the repository root.
36 # Full name of the user visible file, relative to the repository root.
@@ -1567,7 +1567,6 b' class manifestrevlog(object):'
1567 opener,
1567 opener,
1568 tree=b'',
1568 tree=b'',
1569 dirlogcache=None,
1569 dirlogcache=None,
1570 indexfile=None,
1571 treemanifest=False,
1570 treemanifest=False,
1572 ):
1571 ):
1573 """Constructs a new manifest revlog
1572 """Constructs a new manifest revlog
@@ -1598,10 +1597,9 b' class manifestrevlog(object):'
1598 if tree:
1597 if tree:
1599 assert self._treeondisk, b'opts is %r' % opts
1598 assert self._treeondisk, b'opts is %r' % opts
1600
1599
1601 if indexfile is None:
1600 radix = b'00manifest'
1602 indexfile = b'00manifest.i'
1601 if tree:
1603 if tree:
1602 radix = b"meta/" + tree + radix
1604 indexfile = b"meta/" + tree + indexfile
1605
1603
1606 self.tree = tree
1604 self.tree = tree
1607
1605
@@ -1614,7 +1612,7 b' class manifestrevlog(object):'
1614 self._revlog = revlog.revlog(
1612 self._revlog = revlog.revlog(
1615 opener,
1613 opener,
1616 target=(revlog_constants.KIND_MANIFESTLOG, self.tree),
1614 target=(revlog_constants.KIND_MANIFESTLOG, self.tree),
1617 indexfile=indexfile,
1615 radix=radix,
1618 # only root indexfile is cached
1616 # only root indexfile is cached
1619 checkambig=not bool(tree),
1617 checkambig=not bool(tree),
1620 mmaplargeindex=True,
1618 mmaplargeindex=True,
@@ -289,9 +289,8 b' class revlog(object):'
289 self,
289 self,
290 opener,
290 opener,
291 target,
291 target,
292 radix,
292 postfix=None,
293 postfix=None,
293 indexfile=None,
294 datafile=None,
295 checkambig=False,
294 checkambig=False,
296 mmaplargeindex=False,
295 mmaplargeindex=False,
297 censorable=False,
296 censorable=False,
@@ -313,16 +312,19 b' class revlog(object):'
313 accurate value.
312 accurate value.
314 """
313 """
315 self.upperboundcomp = upperboundcomp
314 self.upperboundcomp = upperboundcomp
316 if not indexfile.endswith(b'.i'):
315
317 raise error.ProgrammingError(
316 self.radix = radix
318 b"revlog's indexfile should end with `.i`"
317
319 )
318 if postfix is None:
320 if datafile is None:
319 indexfile = b'%s.i' % self.radix
321 datafile = indexfile[:-2] + b".d"
320 datafile = b'%s.d' % self.radix
322 if postfix is not None:
321 elif postfix == b'a':
323 datafile = b'%s.%s' % (datafile, postfix)
322 indexfile = b'%s.i.a' % self.radix
324 if postfix is not None:
323 datafile = b'%s.d' % self.radix
325 indexfile = b'%s.%s' % (indexfile, postfix)
324 else:
325 indexfile = b'%s.i.%s' % (self.radix, postfix)
326 datafile = b'%s.d.%s' % (self.radix, postfix)
327
326 self._indexfile = indexfile
328 self._indexfile = indexfile
327 self._datafile = datafile
329 self._datafile = datafile
328 self.nodemap_file = None
330 self.nodemap_file = None
@@ -2900,8 +2902,8 b' class revlog(object):'
2900 newrl = revlog(
2902 newrl = revlog(
2901 self.opener,
2903 self.opener,
2902 target=self.target,
2904 target=self.target,
2905 radix=self.radix,
2903 postfix=b'tmpcensored',
2906 postfix=b'tmpcensored',
2904 indexfile=self._indexfile,
2905 censorable=True,
2907 censorable=True,
2906 )
2908 )
2907 newrl._format_version = self._format_version
2909 newrl._format_version = self._format_version
@@ -33,7 +33,7 b' from . import ('
33
33
34
34
35 class unionrevlog(revlog.revlog):
35 class unionrevlog(revlog.revlog):
36 def __init__(self, opener, indexfile, revlog2, linkmapper):
36 def __init__(self, opener, radix, revlog2, linkmapper):
37 # How it works:
37 # How it works:
38 # To retrieve a revision, we just need to know the node id so we can
38 # To retrieve a revision, we just need to know the node id so we can
39 # look it up in revlog2.
39 # look it up in revlog2.
@@ -45,7 +45,7 b' class unionrevlog(revlog.revlog):'
45 if target is None:
45 if target is None:
46 # a revlog wrapper, eg: the manifestlog that is not an actual revlog
46 # a revlog wrapper, eg: the manifestlog that is not an actual revlog
47 target = revlog2._revlog.target
47 target = revlog2._revlog.target
48 revlog.revlog.__init__(self, opener, target=target, indexfile=indexfile)
48 revlog.revlog.__init__(self, opener, target=target, radix=radix)
49 self.revlog2 = revlog2
49 self.revlog2 = revlog2
50
50
51 n = len(self)
51 n = len(self)
@@ -164,9 +164,7 b' class unionchangelog(unionrevlog, change'
164 changelog.changelog.__init__(self, opener)
164 changelog.changelog.__init__(self, opener)
165 linkmapper = None
165 linkmapper = None
166 changelog2 = changelog.changelog(opener2)
166 changelog2 = changelog.changelog(opener2)
167 unionrevlog.__init__(
167 unionrevlog.__init__(self, opener, self.radix, changelog2, linkmapper)
168 self, opener, self._indexfile, changelog2, linkmapper
169 )
170
168
171
169
172 class unionmanifest(unionrevlog, manifest.manifestrevlog):
170 class unionmanifest(unionrevlog, manifest.manifestrevlog):
@@ -174,7 +172,7 b' class unionmanifest(unionrevlog, manifes'
174 manifest.manifestrevlog.__init__(self, nodeconstants, opener)
172 manifest.manifestrevlog.__init__(self, nodeconstants, opener)
175 manifest2 = manifest.manifestrevlog(nodeconstants, opener2)
173 manifest2 = manifest.manifestrevlog(nodeconstants, opener2)
176 unionrevlog.__init__(
174 unionrevlog.__init__(
177 self, opener, self._revlog._indexfile, manifest2, linkmapper
175 self, opener, self._revlog.radix, manifest2, linkmapper
178 )
176 )
179
177
180
178
@@ -183,7 +181,7 b' class unionfilelog(filelog.filelog):'
183 filelog.filelog.__init__(self, opener, path)
181 filelog.filelog.__init__(self, opener, path)
184 filelog2 = filelog.filelog(opener2, path)
182 filelog2 = filelog.filelog(opener2, path)
185 self._revlog = unionrevlog(
183 self._revlog = unionrevlog(
186 opener, self._revlog._indexfile, filelog2._revlog, linkmapper
184 opener, self._revlog.radix, filelog2._revlog, linkmapper
187 )
185 )
188 self._repo = repo
186 self._repo = repo
189 self.repotiprev = self._revlog.repotiprev
187 self.repotiprev = self._revlog.repotiprev
@@ -79,12 +79,11 b' def newtransaction():'
79 return transaction.transaction(report, tvfs, {'plain': tvfs}, b'journal')
79 return transaction.transaction(report, tvfs, {'plain': tvfs}, b'journal')
80
80
81
81
82 def newrevlog(name=b'_testrevlog.i', recreate=False):
82 def newrevlog(name=b'_testrevlog', recreate=False):
83 if recreate:
83 if recreate:
84 tvfs.tryunlink(name)
84 tvfs.tryunlink(name + b'.i')
85 rlog = revlog.revlog(
85 target = (constants.KIND_OTHER, b'test')
86 tvfs, target=(constants.KIND_OTHER, b'test'), indexfile=name
86 rlog = revlog.revlog(tvfs, target=target, radix=name)
87 )
88 return rlog
87 return rlog
89
88
90
89
@@ -112,7 +111,7 b' def appendrev(rlog, text, tr, isext=Fals'
112 rlog._storedeltachains = True
111 rlog._storedeltachains = True
113
112
114
113
115 def addgroupcopy(rlog, tr, destname=b'_destrevlog.i', optimaldelta=True):
114 def addgroupcopy(rlog, tr, destname=b'_destrevlog', optimaldelta=True):
116 """Copy revlog to destname using revlog.addgroup. Return the copied revlog.
115 """Copy revlog to destname using revlog.addgroup. Return the copied revlog.
117
116
118 This emulates push or pull. They use changegroup. Changegroup requires
117 This emulates push or pull. They use changegroup. Changegroup requires
@@ -177,7 +176,7 b" def addgroupcopy(rlog, tr, destname=b'_d"
177 return dlog
176 return dlog
178
177
179
178
180 def lowlevelcopy(rlog, tr, destname=b'_destrevlog.i'):
179 def lowlevelcopy(rlog, tr, destname=b'_destrevlog'):
181 """Like addgroupcopy, but use the low level revlog._addrevision directly.
180 """Like addgroupcopy, but use the low level revlog._addrevision directly.
182
181
183 It exercises some code paths that are hard to reach easily otherwise.
182 It exercises some code paths that are hard to reach easily otherwise.
@@ -427,7 +426,7 b' data = ['
427
426
428
427
429 def makesnapshot(tr):
428 def makesnapshot(tr):
430 rl = newrevlog(name=b'_snaprevlog3.i', recreate=True)
429 rl = newrevlog(name=b'_snaprevlog3', recreate=True)
431 for i in data:
430 for i in data:
432 appendrev(rl, i, tr)
431 appendrev(rl, i, tr)
433 return rl
432 return rl
@@ -483,7 +482,7 b' def maintest():'
483 checkrevlog(rl2, expected)
482 checkrevlog(rl2, expected)
484 print('addgroupcopy test passed')
483 print('addgroupcopy test passed')
485 # Copy via revlog.clone
484 # Copy via revlog.clone
486 rl3 = newrevlog(name=b'_destrevlog3.i', recreate=True)
485 rl3 = newrevlog(name=b'_destrevlog3', recreate=True)
487 rl.clone(tr, rl3)
486 rl.clone(tr, rl3)
488 checkrevlog(rl3, expected)
487 checkrevlog(rl3, expected)
489 print('clone test passed')
488 print('clone test passed')
@@ -49,6 +49,6 b' Test for CVE-2016-3630'
49 >>> from mercurial import revlog, vfs
49 >>> from mercurial import revlog, vfs
50 >>> tvfs = vfs.vfs(b'.')
50 >>> tvfs = vfs.vfs(b'.')
51 >>> tvfs.options = {b'revlogv1': True}
51 >>> tvfs.options = {b'revlogv1': True}
52 >>> rl = revlog.revlog(tvfs, target=(KIND_OTHER, b'test'), indexfile=b'a.i')
52 >>> rl = revlog.revlog(tvfs, target=(KIND_OTHER, b'test'), radix=b'a')
53 >>> rl.revision(1)
53 >>> rl.revision(1)
54 mpatchError(*'patch cannot be decoded'*) (glob)
54 mpatchError(*'patch cannot be decoded'*) (glob)
General Comments 0
You need to be logged in to leave comments. Login now