# HG changeset patch # User Matt Mackall # Date 1191449847 18000 # Node ID 7530334bf301d743df9838af503bbc694271f563 # Parent ff32b2725651c8fd17782a01ef43109c25eb9bbe 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. diff --git a/mercurial/mdiff.py b/mercurial/mdiff.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 diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- 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()