Comments
Patch
@@ -106,30 +106,36 @@ class appender(object):
def write(self, s):
self.data.append(str(s))
self.offset += len(s)
-def delayopener(opener, target, divert, buf):
- def o(name, mode='r'):
+def _divertopener(opener, target):
+ """build an opener that write in `target.a` instead of `target`"""
+ def _divert(name, mode='r'):
if name != target:
return opener(name, mode)
- if divert:
- return opener(name + ".a", mode.replace('a', 'w'))
- # otherwise, divert to memory
+ return opener(name + ".a", mode)
+ return _divert
+
+def _delayopener(opener, target, buf):
+ """build an opener that store chunk in `buf` instead of `target`"""
+ def _delay(name, mode='r'):
+ if name != target:
+ return opener(name, mode)
return appender(opener, name, mode, buf)
- return o
+ return _delay
class changelog(revlog.revlog):
def __init__(self, opener):
revlog.revlog.__init__(self, opener, "00changelog.i")
if self._initempty:
# changelogs don't benefit from generaldelta
self.version &= ~revlog.REVLOGGENERALDELTA
self._generaldelta = False
self._realopener = opener
self._delayed = False
- self._delaybuf = []
+ self._delaybuf = None
self._divert = False
self.filteredrevs = frozenset()
def tip(self):
"""filtered version of revlog.tip"""
@@ -218,31 +224,40 @@ class changelog(revlog.revlog):
raise error.FilteredIndexError(rev)
return super(changelog, self).flags(rev)
def delayupdate(self):
"delay visibility of index updates to other readers"
+
+ if not self._delayed:
+ if len(self) == 0:
+ self._divert = True
+ if self._realopener.exists(self.indexfile + '.a'):
+ self._realopener.unlink(self.indexfile + '.a')
+ self.opener = _divertopener(self._realopener, self.indexfile)
+ else:
+ self._delaybuf = []
+ self.opener = _delayopener(self._realopener, self.indexfile,
+ self._delaybuf)
self._delayed = True
- self._divert = (len(self) == 0)
- self._delaybuf = []
- self.opener = delayopener(self._realopener, self.indexfile,
- self._divert, self._delaybuf)
def finalize(self, tr):
"finalize index updates"
self._delayed = False
self.opener = self._realopener
# move redirected index data back into place
if self._divert:
+ assert not self._delaybuf
tmpname = self.indexfile + ".a"
nfile = self.opener.open(tmpname)
nfile.close()
self.opener.rename(tmpname, self.indexfile)
elif self._delaybuf:
fp = self.opener(self.indexfile, 'a')
fp.write("".join(self._delaybuf))
fp.close()
- self._delaybuf = []
+ self._delaybuf = None
+ self._divert = False
# split when we're done
self.checkinlinesize(tr)
def readpending(self, file):
r = revlog.revlog(self.opener, file)
@@ -260,12 +275,13 @@ class changelog(revlog.revlog):
fp2.write(fp1.read())
# add pending data
fp2.write("".join(self._delaybuf))
fp2.close()
# switch modes so finalize can simply rename
- self._delaybuf = []
+ self._delaybuf = None
self._divert = True
+ self.opener = _divertopener(self._realopener, self.indexfile)
if self._divert:
return True
return False