[PATCH 2 of 2] obsstore: move delete function from obsstore class to repair module

Kostia Balytskyi ikostia at fb.com
Tue Apr 12 07:10:18 EDT 2016


# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com>
# Date 1460459210 25200
#      Tue Apr 12 04:06:50 2016 -0700
# Node ID cd55c17037a71173ec5572b32b951f8007ea164f
# Parent  33e53380588a5953e3f25d4ff66d1b2e27ec7820
obsstore: move delete function from obsstore class to repair module


Since one of the original patches was accepted already and people on the
mailing list still have suggestions as to how this should be improved, I'm
implementing those suggestions in the following patches (this and the ones that
might follow).

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3076,7 +3076,7 @@ def debugobsolete(ui, repo, precursor=No
                                 'of transaction.'))
 
         with repo.lock():
-            n = repo.obsstore.delete(indices)
+            n = repair.deletemarkers(repo.obsstore, indices)
             ui.write(_('deleted %i obsolescense markers\n') % n)
 
         return
diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -628,30 +628,6 @@ class obsstore(object):
         transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
         return len(new)
 
-    def delete(self, indices):
-        """Delete some obsmarkers from store and return how many were deleted
-
-        Indices is a list of ints which are the indices
-        of the markers to be deleted."""
-        if not indices:
-            # we don't want to rewrite the obsstore with the same content
-            return
-
-        left = []
-        current = self._all
-        n = 0
-        for i, m in enumerate(current):
-            if i in indices:
-                n += 1
-                continue
-            left.append(m)
-
-        newobsstore = self.svfs('obsstore', 'w', atomictemp=True)
-        for bytes in encodemarkers(left, True, self._version):
-            newobsstore.write(bytes)
-        newobsstore.close()
-        return n
-
     def mergemarkers(self, transaction, data):
         """merge a binary stream of markers inside the obsstore
 
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -17,6 +17,7 @@ from . import (
     changegroup,
     error,
     exchange,
+    obsolete,
     util,
 )
 
@@ -313,3 +314,32 @@ def stripbmrevset(repo, mark):
                      "ancestors(head() and not bookmark(%s)) - "
                      "ancestors(bookmark() and not bookmark(%s))",
                      mark, mark, mark)
+
+def deletemarkers(obsstore, indices):
+    """Delete some obsmarkers from obsstore and return how many were deleted
+
+    'indices' is a list of ints which are the indices
+    of the markers to be deleted.
+
+    Every invocation of this function completely rewrites the obsstore file,
+    skipping the markers we want to be removed. The new temporary file is
+    created, remaining markers are written there and on .close() this file
+    gets atomically renamed to obsstore, thus guaranteeing consistency."""
+    if not indices:
+        # we don't want to rewrite the obsstore with the same content
+        return
+
+    left = []
+    current = obsstore._all
+    n = 0
+    for i, m in enumerate(current):
+        if i in indices:
+            n += 1
+            continue
+        left.append(m)
+
+    newobsstorefile = obsstore.svfs('obsstore', 'w', atomictemp=True)
+    for bytes in obsolete.encodemarkers(left, True, obsstore._version):
+        newobsstorefile.write(bytes)
+    newobsstorefile.close()
+    return n


More information about the Mercurial-devel mailing list