From 39292679f27a44e03eede16578e5e6bf82fb9e20 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Wed, 10 Jan 2018 17:23:07 +0100 Subject: Clean reconstructed objects outside pack window Object walk reconstructs delta objects but these are not cleaned up after they got out the pack window. Without this change all reconstructed objects reside in memory. restoreOriginal call is moved before calling Size(). Now we can not guarantee that the object is already undeltified. Signed-off-by: Javi Fontan --- plumbing/format/packfile/delta_selector.go | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'plumbing/format/packfile') diff --git a/plumbing/format/packfile/delta_selector.go b/plumbing/format/packfile/delta_selector.go index 8792574..cd38c16 100644 --- a/plumbing/format/packfile/delta_selector.go +++ b/plumbing/format/packfile/delta_selector.go @@ -222,10 +222,16 @@ func (dw *deltaSelector) walk( ) error { indexMap := make(map[plumbing.Hash]*deltaIndex) for i := 0; i < len(objectsToPack); i++ { - // Clean up the index map for anything outside our pack - // window, to save memory. + // Clean up the index map and reconstructed delta objects for anything + // outside our pack window, to save memory. if i > int(packWindow) { - delete(indexMap, objectsToPack[i-int(packWindow)].Hash()) + obj := objectsToPack[i-int(packWindow)] + + delete(indexMap, obj.Hash()) + + if obj.IsDelta() { + obj.Original = nil + } } target := objectsToPack[i] @@ -261,6 +267,16 @@ func (dw *deltaSelector) walk( } func (dw *deltaSelector) tryToDeltify(indexMap map[plumbing.Hash]*deltaIndex, base, target *ObjectToPack) error { + // Original object might not be present if we're reusing a delta, so we + // ensure it is restored. + if err := dw.restoreOriginal(target); err != nil { + return err + } + + if err := dw.restoreOriginal(base); err != nil { + return err + } + // If the sizes are radically different, this is a bad pairing. if target.Size() < base.Size()>>4 { return nil @@ -283,16 +299,6 @@ func (dw *deltaSelector) tryToDeltify(indexMap map[plumbing.Hash]*deltaIndex, ba return nil } - // Original object might not be present if we're reusing a delta, so we - // ensure it is restored. - if err := dw.restoreOriginal(target); err != nil { - return err - } - - if err := dw.restoreOriginal(base); err != nil { - return err - } - if _, ok := indexMap[base.Hash()]; !ok { indexMap[base.Hash()] = new(deltaIndex) } -- cgit