changeset 4275: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
+++ b/mercurial/changelog.py
@@ -85,27 +85,39 @@ class changelog(revlog):
     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
+++ b/tests/test-hup.out
@@ -4,4 +4,4 @@ adding changesets
 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