# HG changeset patch # User Pierre-Yves David # Date 2021-05-03 10:35:14 # Node ID 4f38ada3fc26e5f8aa310a304bd23c1563c55e70 # Parent 682f09857d6978b54ba7dc2c14b1b9fd6fe5e5e2 revlog: move the `trypending` logic from the `changelog` to the `revlog` We move the -reading- logic for the pending's '.a' suffixed index within the revlog class. This is motivated by the fact the logic could be simpler and cleaner if directly handled by the revlog docket. Before we can do so, we need to teach the revlog code about reading "pending" changes. To be honest, we already needed some special casing of the `.a` postfix, so this does not adds much complexity. The logic around -writing- the special '00changelog.i.a' remains in the `changelog` class. Note that the revlog-v2 logic no longer use this logic. The only remaining user of the `postfix` argument is the `censor` logic. We could probably also make the revlog full aware of it (most of the code is already implemented in revlog anyway) and get rid of the `postfix` argument and logic. However this is an adventure for another time. Since we have more information, we add more, paranoid, Programming error in case we detect such "pending reader" trying to do a read (which does not happens anyways). Differential Revision: https://phab.mercurial-scm.org/D10630 diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -396,21 +396,16 @@ class changelog(revlog.revlog): the documentation there. """ - if trypending and opener.exists(b'00changelog.i.a'): - postfix = b'a' - else: - postfix = None - revlog.revlog.__init__( self, opener, target=(revlog_constants.KIND_CHANGELOG, None), radix=b'00changelog', - postfix=postfix, checkambig=True, mmaplargeindex=True, persistentnodemap=opener.options.get(b'persistent-nodemap', False), concurrencychecker=concurrencychecker, + trypending=trypending, ) if self._initempty and (self._format_version == revlog.REVLOGV1): diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -293,13 +293,14 @@ class revlog(object): opener, target, radix, - postfix=None, + postfix=None, # only exist for `tmpcensored` now checkambig=False, mmaplargeindex=False, censorable=False, upperboundcomp=None, persistentnodemap=False, concurrencychecker=None, + trypending=False, ): """ create a revlog object @@ -323,6 +324,7 @@ class revlog(object): self._datafile = None self._nodemap_file = None self.postfix = postfix + self._trypending = trypending self.opener = opener if persistentnodemap: self._nodemap_file = nodemaputil.get_nodemap_file(self) @@ -484,10 +486,12 @@ class revlog(object): new_header, mmapindexthreshold, force_nodemap = self._init_opts() - if self.postfix is None: + if self.postfix is not None: + entry_point = b'%s.i.%s' % (self.radix, self.postfix) + elif self._trypending and self.opener.exists(b'%s.i.a' % self.radix): + entry_point = b'%s.i.a' % self.radix + else: entry_point = b'%s.i' % self.radix - else: - entry_point = b'%s.i.%s' % (self.radix, self.postfix) entry_data = b'' self._initempty = True @@ -545,7 +549,7 @@ class revlog(object): # main docket, so disable it for now. self._nodemap_file = None - if self.postfix is None or self.postfix == b'a': + if self.postfix is None: self._datafile = b'%s.d' % self.radix else: self._datafile = b'%s.d.%s' % (self.radix, self.postfix) @@ -2067,6 +2071,10 @@ class revlog(object): @contextlib.contextmanager def _writing(self, transaction): + if self._trypending: + msg = b'try to write in a `trypending` revlog: %s' + msg %= self.display_id + raise error.ProgrammingError(msg) if self._writinghandles is not None: yield else: diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py +++ b/mercurial/revlogutils/nodemap.py @@ -649,7 +649,7 @@ def _find_node(block, node): def get_nodemap_file(revlog): - if revlog.postfix == b'a': + if revlog._trypending: pending_path = revlog.radix + b".n.a" if revlog.opener.exists(pending_path): return pending_path