revlog: generate trivial deltas against null revision
authorMatt Mackall <mpm@selenic.com>
Wed, 03 Oct 2007 17:17:27 -0500
changeset 5369 7530334bf301
parent 5368 ff32b2725651
child 5370 61462e7d62ed
revlog: generate trivial deltas against null revision To avoid extra memory usage and performance issues with large files, generate a trivial delta header for deltas against the null revision rather than calling the usual delta generator. We append the delta header to meta rather than prepending it to data to avoid a large allocate and copy.
mercurial/mdiff.py
mercurial/revlog.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -245,6 +245,9 @@ def patch(a, bin):
 def get_matching_blocks(a, b):
     return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
 
+def trivialdiffheader(length):
+    return struct.pack(">lll", 0, 0, length)
+
 patches = mpatch.patches
 patchedsize = mpatch.patchedsize
 textdiff = bdiff.bdiff
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1087,9 +1087,13 @@ class revlog(object):
             if infocollect is not None:
                 infocollect(nb)
 
-            d = self.revdiff(a, b)
             p = self.parents(nb)
             meta = nb + p[0] + p[1] + lookup(nb)
+            if a == -1:
+                d = self.revision(nb)
+                meta += mdiff.trivialdiffheader(len(d))
+            else:
+                d = self.revdiff(a, b)
             yield changegroup.genchunk("%s%s" % (meta, d))
 
         yield changegroup.closechunk()