mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
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:
parent
9b104a6a4a
commit
ec8d726ba0
@ -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)):
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user