diff options
author | Javi Fontan <jfontan@gmail.com> | 2018-01-10 17:23:07 +0100 |
---|---|---|
committer | Javi Fontan <jfontan@gmail.com> | 2018-01-11 18:03:53 +0100 |
commit | 39292679f27a44e03eede16578e5e6bf82fb9e20 (patch) | |
tree | e1d85219c10892c7e4ace92614607d23ac0d522b | |
parent | 2547d1d9aa16b7c93b677bb63d8b8daea55d7e86 (diff) | |
download | go-git-39292679f27a44e03eede16578e5e6bf82fb9e20.tar.gz |
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 <javier@sourced.tech>
-rw-r--r-- | plumbing/format/packfile/delta_selector.go | 32 |
1 files changed, 19 insertions, 13 deletions
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) } |