[Updated] D10025: revlogv2: don't assume that the sidedata of the last rev is right after data

Alphare (Raphaël Gomès) phabricator at mercurial-scm.org
Fri Mar 12 11:34:06 UTC 2021


Alphare updated this revision to Diff 26253.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D10025?vs=26088&id=26253

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D10025/new/

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

AFFECTED FILES
  mercurial/revlog.py

CHANGE DETAILS

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -920,7 +920,7 @@
     # Derived from index values.
 
     def end(self, rev):
-        return self.start(rev) + self.length(rev) + self.sidedata_length(rev)
+        return self.start(rev) + self.length(rev)
 
     def parents(self, node):
         i = self.index
@@ -2331,7 +2331,8 @@
 
         curr = len(self)
         prev = curr - 1
-        offset = self.end(prev)
+
+        offset = self._get_data_offset(prev)
 
         if self._concurrencychecker:
             if self._inline:
@@ -2417,6 +2418,29 @@
         self._chainbasecache[curr] = deltainfo.chainbase
         return curr
 
+    def _get_data_offset(self, prev):
+        """Returns the current offset in the (in-transaction) data file.
+        Versions < 2 of the revlog can get this 0(1), revlog v2 needs a docket
+        file to store that information: since sidedata can be rewritten to the
+        end of the data file within a transaction, you can have cases where, for
+        example, rev `n` does not have sidedata while rev `n - 1` does, leading
+        to `n - 1`'s sidedata being written after `n`'s data.
+
+        TODO cache this in a docket file before 5.8."""
+        if self.version & 0xFFFF != REVLOGV2:
+            return self.end(prev)
+
+        offset = 0
+        for rev, entry in enumerate(self.index):
+            sidedata_end = entry[8] + entry[9]
+            if sidedata_end == 0:
+                # Sidedata for a previous rev has potentially been written after
+                # this rev's end, so take the max.
+                offset = max(self.end(rev), offset)
+            else:
+                offset = sidedata_end
+        return offset
+
     def _writeentry(
         self, transaction, ifh, dfh, entry, data, link, offset, sidedata
     ):



To: Alphare, indygreg, #hg-reviewers, marmoute
Cc: mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20210312/14086f79/attachment-0002.html>


More information about the Mercurial-patches mailing list