Patchwork D10565: revlog: split the `version` attribute into its two components

login
register
mail settings
Submitter phabricator
Date May 3, 2021, 11:58 a.m.
Message ID <differential-rev-PHID-DREV-eq3si3ezmtrzglp4h5mw-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48892/
State Superseded
Headers show

Comments

phabricator - May 3, 2021, 11:58 a.m.
marmoute created this revision.
Herald added a reviewer: indygreg.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  The `revlog.version` attribute contained an integer coding 2 different informations:
  
  - the revlog version number
  - a bit field defining some specific feature of the revlog
  
  We now explicitly store the two components independently. This avoid exposing
  the implementation details all around the code and prepare for future revlog
  version that would encode the information in a different way.
  
  In the process we drop the `version` attribute from the interface. It was
  flagged for removal when that interface was created.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10565

AFFECTED FILES
  mercurial/changelog.py
  mercurial/debugcommands.py
  mercurial/interfaces/repository.py
  mercurial/manifest.py
  mercurial/revlog.py
  mercurial/verify.py

CHANGE DETAILS




To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -51,7 +51,7 @@ 
         self.warnings = 0
         self.havecl = len(repo.changelog) > 0
         self.havemf = len(repo.manifestlog.getstorage(b'')) > 0
-        self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
+        self.revlogv1 = repo.changelog._format_version != revlog.REVLOGV0
         self.lrugetctx = util.lrucachefunc(repo.unfiltered().__getitem__)
         self.refersmf = False
         self.fncachewarned = False
@@ -102,7 +102,7 @@ 
         if d[1]:
             self._err(None, _(b"index contains %d extra bytes") % d[1], name)
 
-        if obj.version != revlog.REVLOGV0:
+        if obj._format_version != revlog.REVLOGV0:
             if not self.revlogv1:
                 self._warn(_(b"warning: `%s' uses revlog format 1") % name)
         elif self.revlogv1:
@@ -483,7 +483,7 @@ 
 
         state = {
             # TODO this assumes revlog storage for changelog.
-            b'expectedversion': self.repo.changelog.version & 0xFFFF,
+            b'expectedversion': self.repo.changelog._format_version,
             b'skipflags': self.skipflags,
             # experimental config: censor.policy
             b'erroroncensored': ui.config(b'censor', b'policy') == b'abort',
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -451,10 +451,8 @@ 
 
             versionflags = newversionflags
 
-        self.version = versionflags
-
-        flags = versionflags & ~0xFFFF
-        fmt = versionflags & 0xFFFF
+        flags = self._format_flags = versionflags & ~0xFFFF
+        fmt = self._format_version = versionflags & 0xFFFF
 
         if fmt == REVLOGV0:
             if flags:
@@ -519,7 +517,7 @@ 
                 use_rust_index = self.opener.options.get(b'rust.index')
 
         self._parse_index = parse_index_v1
-        if self.version == REVLOGV0:
+        if self._format_version == REVLOGV0:
             self._parse_index = revlogv0.parse_index_v0
         elif fmt == REVLOGV2:
             self._parse_index = parse_index_v2
@@ -1945,12 +1943,13 @@ 
                     trindex = r
 
         with self._indexfp(b'w') as fp:
-            self.version &= ~FLAG_INLINE_DATA
+            self._format_flags &= ~FLAG_INLINE_DATA
             self._inline = False
             for i in self:
                 e = self.index.entry_binary(i)
                 if i == 0:
-                    header = self.index.pack_header(self.version)
+                    header = self._format_flags | self._format_version
+                    header = self.index.pack_header(header)
                     e = header + e
                 fp.write(e)
 
@@ -2269,13 +2268,14 @@ 
             len(serialized_sidedata),
         )
 
-        if self.version & 0xFFFF != REVLOGV2:
+        if self._format_version != REVLOGV2:
             e = e[:8]
 
         self.index.append(e)
         entry = self.index.entry_binary(curr)
         if curr == 0:
-            header = self.index.pack_header(self.version)
+            header = self._format_flags | self._format_version
+            header = self.index.pack_header(header)
             entry = header + entry
         self._writeentry(
             transaction,
@@ -2307,7 +2307,7 @@ 
         to `n - 1`'s sidedata being written after `n`'s data.
 
         TODO cache this in a docket file before getting out of experimental."""
-        if self.version & 0xFFFF != REVLOGV2:
+        if self._format_version != REVLOGV2:
             return self.end(prev)
 
         offset = 0
@@ -2847,9 +2847,10 @@ 
                 addrevisioncb(self, rev, node)
 
     def censorrevision(self, tr, censornode, tombstone=b''):
-        if (self.version & 0xFFFF) == REVLOGV0:
+        if self._format_version == REVLOGV0:
             raise error.RevlogError(
-                _(b'cannot censor with version %d revlogs') % self.version
+                _(b'cannot censor with version %d revlogs')
+                % self._format_version
             )
 
         censorrev = self.rev(censornode)
@@ -2875,7 +2876,8 @@ 
             datafile=newdatafile,
             censorable=True,
         )
-        newrl.version = self.version
+        newrl._format_version = self._format_version
+        newrl._format_flags = self._format_flags
         newrl._generaldelta = self._generaldelta
         newrl._parse_index = self._parse_index
 
@@ -2947,7 +2949,7 @@ 
         if di:
             yield revlogproblem(error=_(b'index contains %d extra bytes') % di)
 
-        version = self.version & 0xFFFF
+        version = self._format_version
 
         # The verifier tells us what version revlog we should be.
         if version != state[b'expectedversion']:
@@ -3137,6 +3139,7 @@ 
                 self.index.replace_sidedata_info(rev, e[8], e[9], e[0])
                 packed = self.index.entry_binary(rev)
                 if rev == 0:
-                    header = self.index.pack_header(self.version)
+                    header = self._format_flags | self._format_version
+                    header = self.index.pack_header(header)
                     packed = header + packed
                 fp.write(packed)
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1618,7 +1618,6 @@ 
         )
 
         self.index = self._revlog.index
-        self.version = self._revlog.version
         self._generaldelta = self._revlog._generaldelta
 
     def _setupmanifestcachehooks(self, repo):
diff --git a/mercurial/interfaces/repository.py b/mercurial/interfaces/repository.py
--- a/mercurial/interfaces/repository.py
+++ b/mercurial/interfaces/repository.py
@@ -1181,13 +1181,6 @@ 
         """
     )
 
-    version = interfaceutil.Attribute(
-        """Revlog version number.
-
-        TODO this is revlog specific and should not be exposed.
-        """
-    )
-
     _generaldelta = interfaceutil.Attribute(
         """Whether generaldelta storage is being used.
 
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2972,8 +2972,8 @@ 
             )
         return 0
 
-    v = r.version
-    format = v & 0xFFFF
+    format = r._format_version
+    v = r._format_flags
     flags = []
     gdelta = False
     if v & revlog.FLAG_INLINE_DATA:
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -413,10 +413,10 @@ 
             concurrencychecker=concurrencychecker,
         )
 
-        if self._initempty and (self.version & 0xFFFF == revlog.REVLOGV1):
+        if self._initempty and (self._format_version == revlog.REVLOGV1):
             # changelogs don't benefit from generaldelta.
 
-            self.version &= ~revlog.FLAG_GENERALDELTA
+            self._format_flags &= ~revlog.FLAG_GENERALDELTA
             self._generaldelta = False
 
         # Delta chains for changelogs tend to be very small because entries