revlogv2: use a unique filename for index
authorPierre-Yves David <pierre-yves.david@octobus.net>
Tue, 18 May 2021 15:07:17 +0200
changeset 47323 f612db768c7a
parent 47322 1760de72a992
child 47324 0a3fa41fa719
revlogv2: use a unique filename for index Having a unique index will allow for ambiguity less rewriting of revlog content, something useful to clarify handling of some operation like censoring or stripping. Differential Revision: https://phab.mercurial-scm.org/D10771
mercurial/revlogutils/docket.py
tests/test-revlog-v2.t
--- a/mercurial/revlogutils/docket.py	Sat May 22 17:35:54 2021 +0200
+++ b/mercurial/revlogutils/docket.py	Tue May 18 15:07:17 2021 +0200
@@ -88,12 +88,13 @@
 # * 4 bytes: revlog version
 #          |   This is mandatory as docket must be compatible with the previous
 #          |   revlog index header.
+# * 1 bytes: size of index uuid
 # * 8 bytes: size of index-data
 # * 8 bytes: pending size of index-data
 # * 8 bytes: size of data
 # * 8 bytes: pending size of data
 # * 1 bytes: default compression header
-S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LLLLc')
+S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'BLLLLc')
 
 
 class RevlogDocket(object):
@@ -104,6 +105,7 @@
         revlog,
         use_pending=False,
         version_header=None,
+        index_uuid=None,
         index_end=0,
         pending_index_end=0,
         data_end=0,
@@ -116,6 +118,7 @@
         self._radix = revlog.radix
         self._path = revlog._docket_file
         self._opener = revlog.opener
+        self._index_uuid = index_uuid
         # thes asserts should be True as long as we have a single index filename
         assert index_end <= pending_index_end
         assert data_end <= pending_data_end
@@ -134,7 +137,9 @@
     def index_filepath(self):
         """file path to the current index file associated to this docket"""
         # very simplistic version at first
-        return b"%s.idx" % self._radix
+        if self._index_uuid is None:
+            self._index_uuid = make_uid()
+        return b"%s-%s.idx" % (self._radix, self._index_uuid)
 
     @property
     def index_end(self):
@@ -189,13 +194,17 @@
         assert official_data_end <= self._data_end
         data = (
             self._version_header,
+            len(self._index_uuid),
             official_index_end,
             self._index_end,
             official_data_end,
             self._data_end,
             self.default_compression_header,
         )
-        return S_HEADER.pack(*data)
+        s = []
+        s.append(S_HEADER.pack(*data))
+        s.append(self._index_uuid)
+        return b''.join(s)
 
 
 def default_docket(revlog, version_header):
@@ -216,16 +225,21 @@
 def parse_docket(revlog, data, use_pending=False):
     """given some docket data return a docket object for the given revlog"""
     header = S_HEADER.unpack(data[: S_HEADER.size])
+    offset = S_HEADER.size
     version_header = header[0]
-    index_size = header[1]
-    pending_index_size = header[2]
-    data_size = header[3]
-    pending_data_size = header[4]
-    default_compression_header = header[5]
+    index_uuid_size = header[1]
+    index_uuid = data[offset : offset + index_uuid_size]
+    offset += index_uuid_size
+    index_size = header[2]
+    pending_index_size = header[3]
+    data_size = header[4]
+    pending_data_size = header[5]
+    default_compression_header = header[6]
     docket = RevlogDocket(
         revlog,
         use_pending=use_pending,
         version_header=version_header,
+        index_uuid=index_uuid,
         index_end=index_size,
         pending_index_end=pending_index_size,
         data_end=data_size,
--- a/tests/test-revlog-v2.t	Sat May 22 17:35:54 2021 +0200
+++ b/tests/test-revlog-v2.t	Tue May 18 15:07:17 2021 +0200
@@ -67,3 +67,19 @@
   $ f --hexdump --bytes 4 .hg/store/data/foo.i
   .hg/store/data/foo.i:
   0000: 00 00 de ad                                     |....|
+
+The expected files are generated
+--------------------------------
+
+We should have have:
+- a docket
+- a index file with a unique name
+- a data file
+
+  $ ls .hg/store/00changelog* .hg/store/00manifest*
+  .hg/store/00changelog-b870a51b.idx
+  .hg/store/00changelog.d
+  .hg/store/00changelog.i
+  .hg/store/00manifest-88698448.idx
+  .hg/store/00manifest.d
+  .hg/store/00manifest.i