nodemap: automatically "vacuum" the persistent nodemap when too sparse
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 26 Mar 2020 11:55:06 +0100
changeset 44636 c70bcaf7927b
parent 44635 99ea74cbed74
child 44637 02f66b23cba3
nodemap: automatically "vacuum" the persistent nodemap when too sparse We arbitrarily pick "10%" as the threshold. Differential Revision: https://phab.mercurial-scm.org/D8193
mercurial/configitems.py
mercurial/revlogutils/nodemap.py
tests/test-persistent-nodemap.t
--- a/mercurial/configitems.py	Fri Feb 28 03:18:57 2020 +0100
+++ b/mercurial/configitems.py	Thu Mar 26 11:55:06 2020 +0100
@@ -407,7 +407,6 @@
 )
 # TODO before getting `persistent-nodemap` out of experimental
 #
-# * regenerate a new nodemap when the unused/total ration is to high
 # * decide for a "status" of the persistent nodemap and associated location
 #   - part of the store next the revlog itself (new requirements)
 #   - part of the cache directory
--- a/mercurial/revlogutils/nodemap.py	Fri Feb 28 03:18:57 2020 +0100
+++ b/mercurial/revlogutils/nodemap.py	Thu Mar 26 11:55:06 2020 +0100
@@ -143,13 +143,16 @@
             data_changed_count,
             data,
         ) = revlog.index.nodemap_data_incremental()
+        new_length = target_docket.data_length + len(data)
+        new_unused = target_docket.data_unused + data_changed_count
         if src_docket != target_docket:
             data = None
+        elif new_length <= (new_unused * 10):  # under 10% of unused data
+            data = None
         else:
             datafile = _rawdata_filepath(revlog, target_docket)
             # EXP-TODO: if this is a cache, this should use a cache vfs, not a
             # store vfs
-            new_length = target_docket.data_length + len(data)
             tr.add(datafile, target_docket.data_length)
             with revlog.opener(datafile, b'r+') as fd:
                 fd.seek(target_docket.data_length)
@@ -162,7 +165,7 @@
                         fd.flush()
                         new_data = util.buffer(util.mmapread(fd, new_length))
             target_docket.data_length = new_length
-            target_docket.data_unused += data_changed_count
+            target_docket.data_unused = new_unused
 
     if data is None:
         # otherwise fallback to a full new export
--- a/tests/test-persistent-nodemap.t	Fri Feb 28 03:18:57 2020 +0100
+++ b/tests/test-persistent-nodemap.t	Thu Mar 26 11:55:06 2020 +0100
@@ -278,12 +278,12 @@
   tip-rev: 5002
   tip-node: 42bf3068c7ddfdfded53c4eb11d02266faeebfee
   data-length: 123456 (pure !)
-  data-length: 246464 (rust !)
+  data-length: 123008 (rust !)
   data-length: 123008 (no-pure no-rust !)
   data-unused: 448 (pure !)
-  data-unused: 123904 (rust !)
+  data-unused: 0 (rust !)
   data-unused: 0 (no-pure no-rust !)
-  data-unused: 50.273% (rust !)
+  data-unused: 0.000% (rust !)
   data-unused: 0.363% (pure !)
   data-unused: 0.000% (no-pure no-rust !)