diff mercurial/dirstate.py @ 48793:6e559391f96e

tracked-key: remove the dual write and rename to tracked-hint The dual-write approach was mostly useless. As explained in the previous version of the help, the key had to be read twice before we could cache a value. However this "read twice" limitation actually also apply to any usage of the key. If some operation wants to rely of the "same value == same tracked set" property it would need to read the value before, and after running that operation (or at least, after, in all cases). So it cannot be sure the operation it did is "valid" until checking the key after the operation. As a resultat such operation can only be read-only or rollbackable. This reduce the utility of the "same value == same tracked set" a lot. So it seems simpler to drop the double write and to update the documentation to highlight that this file does not garantee race-free operation. As a result the "key" is demoted to a "hint". Documentation is updated accordingly. Differential Revision: https://phab.mercurial-scm.org/D12201
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 17 Feb 2022 07:34:49 +0100
parents 5ba24e886cec
children 6000f5b25c9b
line wrap: on
line diff
--- a/mercurial/dirstate.py	Thu Feb 17 06:41:54 2022 +0100
+++ b/mercurial/dirstate.py	Thu Feb 17 07:34:49 2022 +0100
@@ -101,7 +101,7 @@
         sparsematchfn,
         nodeconstants,
         use_dirstate_v2,
-        use_tracked_key=False,
+        use_tracked_hint=False,
     ):
         """Create a new dirstate object.
 
@@ -110,7 +110,7 @@
         the dirstate.
         """
         self._use_dirstate_v2 = use_dirstate_v2
-        self._use_tracked_key = use_tracked_key
+        self._use_tracked_hint = use_tracked_hint
         self._nodeconstants = nodeconstants
         self._opener = opener
         self._validate = validate
@@ -127,7 +127,7 @@
         self._filecache = {}
         self._parentwriters = 0
         self._filename = b'dirstate'
-        self._filename_tk = b'dirstate-tracked-key'
+        self._filename_th = b'dirstate-tracked-hint'
         self._pendingfilename = b'%s.pending' % self._filename
         self._plchangecallbacks = {}
         self._origpl = None
@@ -721,17 +721,9 @@
         if not self._dirty:
             return
 
-        write_key = self._use_tracked_key and self._dirty_tracked_set
+        write_key = self._use_tracked_hint and self._dirty_tracked_set
         if tr:
             # delay writing in-memory changes out
-            if write_key:
-                tr.addfilegenerator(
-                    b'dirstate-0-key-pre',
-                    (self._filename_tk,),
-                    lambda f: self._write_tracked_key(tr, f),
-                    location=b'plain',
-                    post_finalize=True,
-                )
             tr.addfilegenerator(
                 b'dirstate-1-main',
                 (self._filename,),
@@ -742,33 +734,28 @@
             if write_key:
                 tr.addfilegenerator(
                     b'dirstate-2-key-post',
-                    (self._filename_tk,),
-                    lambda f: self._write_tracked_key(tr, f),
+                    (self._filename_th,),
+                    lambda f: self._write_tracked_hint(tr, f),
                     location=b'plain',
                     post_finalize=True,
                 )
             return
 
         file = lambda f: self._opener(f, b"w", atomictemp=True, checkambig=True)
-        if write_key:
-            # we change the key-file before changing the dirstate to make sure
-            # reading invalidate there cache before we start writing
-            with file(self._filename_tk) as f:
-                self._write_tracked_key(tr, f)
         with file(self._filename) as f:
             self._writedirstate(tr, f)
         if write_key:
             # we update the key-file after writing to make sure reader have a
             # key that match the newly written content
-            with file(self._filename_tk) as f:
-                self._write_tracked_key(tr, f)
+            with file(self._filename_th) as f:
+                self._write_tracked_hint(tr, f)
 
-    def delete_tracked_key(self):
-        """remove the tracked_key file
+    def delete_tracked_hint(self):
+        """remove the tracked_hint file
 
         To be used by format downgrades operation"""
-        self._opener.unlink(self._filename_tk)
-        self._use_tracked_key = False
+        self._opener.unlink(self._filename_th)
+        self._use_tracked_hint = False
 
     def addparentchangecallback(self, category, callback):
         """add a callback to be called when the wd parents are changed
@@ -793,7 +780,7 @@
         self._dirty = False
         self._dirty_tracked_set = False
 
-    def _write_tracked_key(self, tr, f):
+    def _write_tracked_hint(self, tr, f):
         key = node.hex(uuid.uuid4().bytes)
         f.write(b"1\n%s\n" % key)  # 1 is the format version