comparison mercurial/localrepo.py @ 44791:b81486b609a3

nodemap: gate the feature behind a new requirement Now that the feature is working smoothly, a question was still open, should we gate the feature behind a new requirement or just treat it as a cache to be warmed by those who can and ignored by other. The advantage of using the cache approach is a transparent upgrade/downgrade story, making the feature easier to move to. However having out of date cache can come with a significant performance hit for process who expect an up to date cache but found none. In this case the file needs to be stored under `.hg/cache`. The "requirement" approach guarantee that the persistent nodemap is up to date. However, it comes with a less flexible activation story since an explicite upgrade is required. In this case the file can be stored in `.hg/store`. This wiki page is relevant to this questions: https://www.mercurial-scm.org/wiki/ComputedIndexPlan So which one should we take? Another element came into plan, the persistent nodemap use the `add` method of the transaction, it is used to keep track of a file content before a transaction in case we need to rollback it back. It turns out that the `transaction.add` API does not support file stored anywhere than `.hg/store`. Making it support file stored elsewhere is possible, require a change in on disk transaction format. Updating on disk file requires? introducing a new requirements. As a result, we pick the second option "gating the persistent nodemap behind a new requirements". Differential Revision: https://phab.mercurial-scm.org/D8417
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 14 Apr 2020 03:16:23 +0200
parents 6493f0a567c2
children 5e3c718692bb
comparison
equal deleted inserted replaced
44790:261e71752d1f 44791:b81486b609a3
443 443
444 # A repository with the the copies-sidedata-changeset requirement will store 444 # A repository with the the copies-sidedata-changeset requirement will store
445 # copies related information in changeset's sidedata. 445 # copies related information in changeset's sidedata.
446 COPIESSDC_REQUIREMENT = b'exp-copies-sidedata-changeset' 446 COPIESSDC_REQUIREMENT = b'exp-copies-sidedata-changeset'
447 447
448 # The repository use persistent nodemap for the changelog and the manifest.
449 NODEMAP_REQUIREMENT = b'persistent-nodemap'
450
448 # Functions receiving (ui, features) that extensions can register to impact 451 # Functions receiving (ui, features) that extensions can register to impact
449 # the ability to load repositories with custom requirements. Only 452 # the ability to load repositories with custom requirements. Only
450 # functions defined in loaded extensions are called. 453 # functions defined in loaded extensions are called.
451 # 454 #
452 # The function receives a set of requirement strings that the repository 455 # The function receives a set of requirement strings that the repository
931 if repository.NARROW_REQUIREMENT in requirements: 934 if repository.NARROW_REQUIREMENT in requirements:
932 options[b'enableellipsis'] = True 935 options[b'enableellipsis'] = True
933 936
934 if ui.configbool(b'experimental', b'rust.index'): 937 if ui.configbool(b'experimental', b'rust.index'):
935 options[b'rust.index'] = True 938 options[b'rust.index'] = True
936 if ui.configbool(b'experimental', b'exp-persistent-nodemap'): 939 if NODEMAP_REQUIREMENT in requirements:
937 options[b'exp-persistent-nodemap'] = True 940 options[b'exp-persistent-nodemap'] = True
938 if ui.configbool(b'experimental', b'exp-persistent-nodemap.mmap'): 941 if ui.configbool(b'experimental', b'exp-persistent-nodemap.mmap'):
939 options[b'exp-persistent-nodemap.mmap'] = True 942 options[b'exp-persistent-nodemap.mmap'] = True
940 epnm = ui.config(b'experimental', b'exp-persistent-nodemap.mode') 943 epnm = ui.config(b'experimental', b'exp-persistent-nodemap.mode')
941 options[b'exp-persistent-nodemap.mode'] = epnm 944 options[b'exp-persistent-nodemap.mode'] = epnm
1021 b'treemanifest', 1024 b'treemanifest',
1022 COPIESSDC_REQUIREMENT, 1025 COPIESSDC_REQUIREMENT,
1023 REVLOGV2_REQUIREMENT, 1026 REVLOGV2_REQUIREMENT,
1024 SIDEDATA_REQUIREMENT, 1027 SIDEDATA_REQUIREMENT,
1025 SPARSEREVLOG_REQUIREMENT, 1028 SPARSEREVLOG_REQUIREMENT,
1029 NODEMAP_REQUIREMENT,
1026 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT, 1030 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
1027 } 1031 }
1028 _basesupported = supportedformats | { 1032 _basesupported = supportedformats | {
1029 b'store', 1033 b'store',
1030 b'fncache', 1034 b'fncache',
3658 requirements.add(b'lfs') 3662 requirements.add(b'lfs')
3659 3663
3660 if ui.configbool(b'format', b'bookmarks-in-store'): 3664 if ui.configbool(b'format', b'bookmarks-in-store'):
3661 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT) 3665 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3662 3666
3667 if ui.configbool(b'experimental', b'exp-persistent-nodemap'):
3668 requirements.add(NODEMAP_REQUIREMENT)
3669
3663 return requirements 3670 return requirements
3664 3671
3665 3672
3666 def filterknowncreateopts(ui, createopts): 3673 def filterknowncreateopts(ui, createopts):
3667 """Filters a dict of repo creation options against options that are known. 3674 """Filters a dict of repo creation options against options that are known.