diff options
author | Jeremy Stribling <strib@alum.mit.edu> | 2017-08-25 16:26:04 -0700 |
---|---|---|
committer | Jeremy Stribling <strib@alum.mit.edu> | 2017-08-28 10:10:16 -0700 |
commit | cdddb7a38b448f999a54e4e4ef14b5c62c198676 (patch) | |
tree | ad4f316055152375d333e0acba65e491936f7c1a | |
parent | bff1d06e40f70566a779880b2edeb53ad1930609 (diff) | |
download | go-git-cdddb7a38b448f999a54e4e4ef14b5c62c198676.tar.gz |
plumbing: use sliding window in delta calculations, like git CL
This sets a default sliding window of 10 for the delta calculation,
just like git CL:
https://git-scm.com/docs/git-pack-objects#git-pack-objects---windowltngt
For a big-ish repo with 35K objects (17K commits), this reduced the
time for calling `deltaSelection.walk` during a push from more than 14
minutes to about a minute.
-rw-r--r-- | plumbing/format/packfile/delta_selector.go | 5 | ||||
-rw-r--r-- | plumbing/format/packfile/delta_selector_test.go | 19 |
2 files changed, 23 insertions, 1 deletions
diff --git a/plumbing/format/packfile/delta_selector.go b/plumbing/format/packfile/delta_selector.go index efcbd53..cc0ae0f 100644 --- a/plumbing/format/packfile/delta_selector.go +++ b/plumbing/format/packfile/delta_selector.go @@ -8,6 +8,9 @@ import ( ) const ( + // How far back in the sorted list to search for deltas. 10 is + // the default in command line git. + deltaWindowSize = 10 // deltas based on deltas, how many steps we can do. // 50 is the default value used in JGit maxDepth = int64(50) @@ -184,7 +187,7 @@ func (dw *deltaSelector) walk(objectsToPack []*ObjectToPack) error { continue } - for j := i - 1; j >= 0; j-- { + for j := i - 1; j >= 0 && i-j < deltaWindowSize; j-- { base := objectsToPack[j] // Objects must use only the same type as their delta base. // Since objectsToPack is sorted by type and size, once we find diff --git a/plumbing/format/packfile/delta_selector_test.go b/plumbing/format/packfile/delta_selector_test.go index cbbbc89..ca4a96b 100644 --- a/plumbing/format/packfile/delta_selector_test.go +++ b/plumbing/format/packfile/delta_selector_test.go @@ -196,6 +196,25 @@ func (s *DeltaSelectorSuite) TestObjectsToPack(c *C) { c.Assert(otp[2].Original, Equals, s.store.Objects[s.hashes["o3"]]) c.Assert(otp[2].IsDelta(), Equals, true) c.Assert(otp[2].Depth, Equals, 2) + + // Check that objects outside of the sliding window don't produce + // a delta. + hashes = make([]plumbing.Hash, 0, deltaWindowSize+2) + hashes = append(hashes, s.hashes["base"]) + for i := 0; i < deltaWindowSize; i++ { + hashes = append(hashes, s.hashes["smallTarget"]) + } + hashes = append(hashes, s.hashes["target"]) + + // Don't sort so we can easily check the sliding window without + // creating a bunch of new objects. + otp, err = s.ds.objectsToPack(hashes) + c.Assert(err, IsNil) + err = s.ds.walk(otp) + c.Assert(err, IsNil) + c.Assert(len(otp), Equals, deltaWindowSize+2) + targetIdx := len(otp) - 1 + c.Assert(otp[targetIdx].IsDelta(), Equals, false) } func (s *DeltaSelectorSuite) TestMaxDepth(c *C) { |