changelog: optimize delayed updates for clone vs pull
authorMatt Mackall <mpm@selenic.com>
Sat, 24 Mar 2007 02:47:33 -0500
changeset 4269 73c918c71300
parent 4268 f38f90a177dc
child 4276 cb6107f78b92
changelog: optimize delayed updates for clone vs pull pull index updates get redirected to memory, then appended on finalize clone index updates get sent to 00changelog.i.a, then renamed on finalize
mercurial/changelog.py
tests/test-hup.out
--- a/mercurial/changelog.py	Sat Mar 24 02:45:08 2007 -0500
+++ b/mercurial/changelog.py	Sat Mar 24 02:47:33 2007 -0500
@@ -85,27 +85,39 @@
     def delayupdate(self):
         "delay visibility of index updates to other readers"
         self._realopener = self.opener
-        self.opener = self._appendopener
+        self.opener = self._delayopener
+        self._delaycount = self.count()
         self._delaybuf = []
+        self._delayname = None
 
     def finalize(self, tr):
         "finalize index updates"
         self.opener = self._realopener
-        if self._delaybuf:
+        # move redirected index data back into place
+        if self._delayname:
+            util.rename(self._delayname + ".a", self._delayname)
+        elif self._delaybuf:
             fp = self.opener(self.indexfile, 'a')
             fp.write("".join(self._delaybuf))
             fp.close()
             del self._delaybuf
+        # split when we're done
         self.checkinlinesize(tr)
 
-    def _appendopener(self, name, mode='r'):
+    def _delayopener(self, name, mode='r'):
         fp = self._realopener(name, mode)
+        # only divert the index
         if not name == self.indexfile:
             return fp
+        # if we're doing an initial clone, divert to another file
+        if self._delaycount == 0:
+            self._delayname = fp.name
+            return self._realopener(name + ".a", mode)
+        # otherwise, divert to memory
         return appender(fp, self._delaybuf)
 
     def checkinlinesize(self, tr, fp=None):
-        if self.opener == self._appendopener:
+        if self.opener == self._delayopener:
             return
         return revlog.checkinlinesize(self, tr, fp)
 
--- a/tests/test-hup.out	Sat Mar 24 02:45:08 2007 -0500
+++ b/tests/test-hup.out	Sat Mar 24 02:47:33 2007 -0500
@@ -4,4 +4,4 @@
 killed!
 transaction abort!
 rollback completed
-.hg/00changelog.i .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i
+.hg/00changelog.i .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a