diff mercurial/changelog.py @ 4269:73c918c71300

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
author Matt Mackall <mpm@selenic.com>
date Sat, 24 Mar 2007 02:47:33 -0500
parents cd7b36b7869c
children
line wrap: on
line diff
--- 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)