[PATCH] transaction: fix backwards compatibility of atomic groups

Henrik Stuart henrik.stuart at edlund.dk
Mon May 11 08:30:09 CDT 2009


# HG changeset patch
# User Henrik Stuart <hg at hstuart.dk>
# Date 1241697157 -7200
# Node ID 46998402ac99ea78a5ba3fd463feb5d8035f8c01
# Parent  db52cc4f2f97e6a125d2f71363230357c0100570
transaction: add atomic groups to transaction logic

When performing a strip operation on a repository, it is vital that all the
truncations are performed, or that none of them are. This is done by adding
support for writing a number of entries in a single operation.

Co-contributor: Sune Foldager <cryo at cyanite.org>

diff -r db52cc4f2f97 -r 46998402ac99 mercurial/repair.py
--- a/mercurial/repair.py	Thu May 07 01:33:45 2009 +0200
+++ b/mercurial/repair.py	Thu May 07 13:52:37 2009 +0200
@@ -124,10 +124,12 @@
     tr = repo.transaction()
     offset = len(tr.entries)
 
+    tr.start_atomic()
     cl.strip(striprev, tr)
     mfst.strip(striprev, tr)
     for f in fs:
         f.strip(striprev, tr)
+    tr.end_atomic()
 
     try:
         for i in xrange(offset, len(tr.entries)):
diff -r db52cc4f2f97 -r 46998402ac99 mercurial/transaction.py
--- a/mercurial/transaction.py	Thu May 07 01:33:45 2009 +0200
+++ b/mercurial/transaction.py	Thu May 07 13:52:37 2009 +0200
@@ -51,6 +51,7 @@
         self.entries = []
         self.map = {}
         self.journal = journal
+        self.queue = []
 
         self.file = open(self.journal, "w")
         if createmode is not None:
@@ -62,8 +63,25 @@
             self.file.close()
 
     @active
+    def start_atomic(self):
+        self.queue.append([])
+
+    @active
+    def end_atomic(self):
+        q = self.queue.pop()
+        d = ''.join(['%s\0%d\n' % (x[0], x[1]) for x in q])
+        self.entries.extend(q)
+        self.file.write(d)
+        self.file.flush()
+
+    @active
     def add(self, file, offset, data=None):
         if file in self.map: return
+
+        if self.queue:
+            self.queue[-1].append((file, offset, data))
+            return
+
         self.entries.append((file, offset, data))
         self.map[file] = len(self.entries) - 1
         # add enough data to the journal to do the truncate
@@ -78,6 +96,11 @@
 
     @active
     def replace(self, file, offset, data=None):
+        '''
+        replace can only replace already committed entries
+        that are not pending in the queue
+        '''
+
         if file not in self.map:
             raise KeyError(file)
         index = self.map[file]


More information about the Mercurial-devel mailing list