aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavi Fontan <jfontan@gmail.com>2018-01-10 17:23:07 +0100
committerJavi Fontan <jfontan@gmail.com>2018-01-11 18:03:53 +0100
commit39292679f27a44e03eede16578e5e6bf82fb9e20 (patch)
treee1d85219c10892c7e4ace92614607d23ac0d522b
parent2547d1d9aa16b7c93b677bb63d8b8daea55d7e86 (diff)
downloadgo-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.go32
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)
}