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@cyanite.org>
This commit is contained in:
Henrik Stuart 2009-05-11 21:12:40 +02:00
parent 9b104a6a4a
commit ec8d726ba0
2 changed files with 25 additions and 0 deletions

View File

@ -125,10 +125,12 @@ def strip(ui, repo, node, backup="all"):
tr = repo.transaction()
offset = len(tr.entries)
tr.startgroup()
cl.strip(striprev, tr)
mfst.strip(striprev, tr)
for f in fs:
f.strip(striprev, tr)
tr.endgroup()
try:
for i in xrange(offset, len(tr.entries)):

View File

@ -51,6 +51,7 @@ class transaction(object):
self.entries = []
self.map = {}
self.journal = journal
self._queue = []
self.file = open(self.journal, "w")
if createmode is not None:
@ -61,9 +62,26 @@ class transaction(object):
if self.entries: self._abort()
self.file.close()
@active
def startgroup(self):
self._queue.append([])
@active
def endgroup(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 @@ class transaction(object):
@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]