Show More
@@ -385,6 +385,9 class changelog(revlog.revlog): | |||
|
385 | 385 | datafile=datafile, |
|
386 | 386 | checkambig=True, |
|
387 | 387 | mmaplargeindex=True, |
|
388 | persistentnodemap=opener.options.get( | |
|
389 | b'exp-persistent-nodemap', False | |
|
390 | ), | |
|
388 | 391 | ) |
|
389 | 392 | |
|
390 | 393 | if self._initempty and (self.version & 0xFFFF == revlog.REVLOGV1): |
@@ -660,6 +660,9 coreconfigitem( | |||
|
660 | 660 | b'experimental', b'rust.index', default=False, |
|
661 | 661 | ) |
|
662 | 662 | coreconfigitem( |
|
663 | b'experimental', b'exp-persistent-nodemap', default=False, | |
|
664 | ) | |
|
665 | coreconfigitem( | |
|
663 | 666 | b'experimental', b'server.filesdata.recommended-batch-size', default=50000, |
|
664 | 667 | ) |
|
665 | 668 | coreconfigitem( |
@@ -932,6 +932,8 def resolverevlogstorevfsoptions(ui, req | |||
|
932 | 932 | |
|
933 | 933 | if ui.configbool(b'experimental', b'rust.index'): |
|
934 | 934 | options[b'rust.index'] = True |
|
935 | if ui.configbool(b'experimental', b'exp-persistent-nodemap'): | |
|
936 | options[b'exp-persistent-nodemap'] = True | |
|
935 | 937 | |
|
936 | 938 | return options |
|
937 | 939 |
@@ -407,6 +407,7 class revlog(object): | |||
|
407 | 407 | mmaplargeindex=False, |
|
408 | 408 | censorable=False, |
|
409 | 409 | upperboundcomp=None, |
|
410 | persistentnodemap=False, | |
|
410 | 411 | ): |
|
411 | 412 | """ |
|
412 | 413 | create a revlog object |
@@ -418,6 +419,10 class revlog(object): | |||
|
418 | 419 | self.upperboundcomp = upperboundcomp |
|
419 | 420 | self.indexfile = indexfile |
|
420 | 421 | self.datafile = datafile or (indexfile[:-2] + b".d") |
|
422 | self.nodemap_file = None | |
|
423 | if persistentnodemap: | |
|
424 | self.nodemap_file = indexfile[:-2] + b".n" | |
|
425 | ||
|
421 | 426 | self.opener = opener |
|
422 | 427 | # When True, indexfile is opened with checkambig=True at writing, to |
|
423 | 428 | # avoid file stat ambiguity. |
@@ -2286,6 +2291,7 class revlog(object): | |||
|
2286 | 2291 | ifh.write(data[0]) |
|
2287 | 2292 | ifh.write(data[1]) |
|
2288 | 2293 | self._enforceinlinesize(transaction, ifh) |
|
2294 | nodemaputil.setup_persistent_nodemap(transaction, self) | |
|
2289 | 2295 | |
|
2290 | 2296 | def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None): |
|
2291 | 2297 | """ |
@@ -22,6 +22,39 class NodeMap(dict): | |||
|
22 | 22 | raise error.RevlogError(b'unknown node: %s' % x) |
|
23 | 23 | |
|
24 | 24 | |
|
25 | def setup_persistent_nodemap(tr, revlog): | |
|
26 | """Install whatever is needed transaction side to persist a nodemap on disk | |
|
27 | ||
|
28 | (only actually persist the nodemap if this is relevant for this revlog) | |
|
29 | """ | |
|
30 | if revlog.nodemap_file is None: | |
|
31 | return # we do not use persistent_nodemap on this revlog | |
|
32 | callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file | |
|
33 | if tr.hasfinalize(callback_id): | |
|
34 | return # no need to register again | |
|
35 | tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog)) | |
|
36 | ||
|
37 | ||
|
38 | def _persist_nodemap(tr, revlog): | |
|
39 | """Write nodemap data on disk for a given revlog | |
|
40 | """ | |
|
41 | if getattr(revlog, 'filteredrevs', ()): | |
|
42 | raise error.ProgrammingError( | |
|
43 | "cannot persist nodemap of a filtered changelog" | |
|
44 | ) | |
|
45 | if revlog.nodemap_file is None: | |
|
46 | msg = "calling persist nodemap on a revlog without the feature enableb" | |
|
47 | raise error.ProgrammingError(msg) | |
|
48 | data = persistent_data(revlog.index) | |
|
49 | # EXP-TODO: if this is a cache, this should use a cache vfs, not a | |
|
50 | # store vfs | |
|
51 | with revlog.opener(revlog.nodemap_file, b'w') as f: | |
|
52 | f.write(data) | |
|
53 | # EXP-TODO: if the transaction abort, we should remove the new data and | |
|
54 | # reinstall the old one. (This will be simpler when the file format get a | |
|
55 | # bit more advanced) | |
|
56 | ||
|
57 | ||
|
25 | 58 | ### Nodemap Trie |
|
26 | 59 | # |
|
27 | 60 | # This is a simple reference implementation to compute and persist a nodemap |
@@ -5,8 +5,14 Test the persistent on-disk nodemap | |||
|
5 | 5 | |
|
6 | 6 | $ hg init test-repo |
|
7 | 7 | $ cd test-repo |
|
8 | $ cat << EOF >> .hg/hgrc | |
|
9 | > [experimental] | |
|
10 | > exp-persistent-nodemap=yes | |
|
11 | > EOF | |
|
8 | 12 | $ hg debugbuilddag .+5000 |
|
9 |
$ hg debugnodemap --dump | f --sha256 -- |
|
|
13 | $ hg debugnodemap --dump | f --sha256 --size | |
|
14 | size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 | |
|
15 | $ f --sha256 --bytes=256 --hexdump --size < .hg/store/00changelog.n | |
|
10 | 16 | size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 |
|
11 | 17 | 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| |
|
12 | 18 | 0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff |................| |
General Comments 0
You need to be logged in to leave comments.
Login now