changeset 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 f38f90a177dc
children cb6107f78b92
files mercurial/changelog.py tests/test-hup.out
diffstat 2 files changed, 17 insertions(+), 5 deletions(-) [+]
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)
 
--- 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