diff options
author | Santiago M. Mola <santi@mola.io> | 2017-07-25 15:00:01 +0200 |
---|---|---|
committer | Santiago M. Mola <santi@mola.io> | 2017-07-27 15:33:14 +0200 |
commit | 87413ced43b02a41359ce7a1a07ab41aec6ee313 (patch) | |
tree | 07975422ab63bfbb13aefc1a2d53d757c7342848 /plumbing/format/packfile/encoder_advanced_test.go | |
parent | 3834038893d5cacb49e5f2786ad955d26f666546 (diff) | |
download | go-git-87413ced43b02a41359ce7a1a07ab41aec6ee313.tar.gz |
storage: reuse deltas from packfiles
* plumbing: add DeltaObject interface for EncodedObjects that
are deltas and hold additional information about them, such
as the hash of the base object.
* plumbing/storer: add DeltaObjectStorer interface for object
storers that can return DeltaObject. Note that calls to
EncodedObject will never return instances of DeltaObject.
That requires explicit calls to DeltaObject.
* storage/filesystem: implement DeltaObjectStorer interface.
* plumbing/packfile: packfile encoder now supports reusing
deltas that are already computed (e.g. from an existing
packfile) if the storage implements DeltaObjectStorer.
Reusing deltas boosts performance of packfile generation
(e.g. on push).
Diffstat (limited to 'plumbing/format/packfile/encoder_advanced_test.go')
-rw-r--r-- | plumbing/format/packfile/encoder_advanced_test.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/plumbing/format/packfile/encoder_advanced_test.go b/plumbing/format/packfile/encoder_advanced_test.go new file mode 100644 index 0000000..d92e2c4 --- /dev/null +++ b/plumbing/format/packfile/encoder_advanced_test.go @@ -0,0 +1,91 @@ +package packfile_test + +import ( + "bytes" + "math/rand" + + "gopkg.in/src-d/go-git.v4/plumbing" + . "gopkg.in/src-d/go-git.v4/plumbing/format/packfile" + "gopkg.in/src-d/go-git.v4/plumbing/storer" + "gopkg.in/src-d/go-git.v4/storage/filesystem" + "gopkg.in/src-d/go-git.v4/storage/memory" + + "github.com/src-d/go-git-fixtures" + . "gopkg.in/check.v1" +) + +type EncoderAdvancedSuite struct { + fixtures.Suite +} + +var _ = Suite(&EncoderAdvancedSuite{}) + +func (s *EncoderAdvancedSuite) TestEncodeDecode(c *C) { + fixs := fixtures.Basic().ByTag("packfile").ByTag(".git") + fixs = append(fixs, fixtures.ByURL("https://github.com/src-d/go-git.git"). + ByTag("packfile").ByTag(".git").One()) + fixs.Test(c, func(f *fixtures.Fixture) { + storage, err := filesystem.NewStorage(f.DotGit()) + c.Assert(err, IsNil) + s.testEncodeDecode(c, storage) + }) + +} + +func (s *EncoderAdvancedSuite) testEncodeDecode(c *C, storage storer.Storer) { + + objIter, err := storage.IterEncodedObjects(plumbing.AnyObject) + c.Assert(err, IsNil) + + expectedObjects := map[plumbing.Hash]bool{} + var hashes []plumbing.Hash + err = objIter.ForEach(func(o plumbing.EncodedObject) error { + expectedObjects[o.Hash()] = true + hashes = append(hashes, o.Hash()) + return err + + }) + c.Assert(err, IsNil) + + // Shuffle hashes to avoid delta selector getting order right just because + // the initial order is correct. + auxHashes := make([]plumbing.Hash, len(hashes)) + for i, j := range rand.Perm(len(hashes)) { + auxHashes[j] = hashes[i] + } + hashes = auxHashes + + buf := bytes.NewBuffer(nil) + enc := NewEncoder(buf, storage, false) + _, err = enc.Encode(hashes) + c.Assert(err, IsNil) + + scanner := NewScanner(buf) + storage = memory.NewStorage() + d, err := NewDecoder(scanner, storage) + c.Assert(err, IsNil) + _, err = d.Decode() + c.Assert(err, IsNil) + + objIter, err = storage.IterEncodedObjects(plumbing.AnyObject) + c.Assert(err, IsNil) + obtainedObjects := map[plumbing.Hash]bool{} + err = objIter.ForEach(func(o plumbing.EncodedObject) error { + obtainedObjects[o.Hash()] = true + return nil + }) + c.Assert(err, IsNil) + c.Assert(obtainedObjects, DeepEquals, expectedObjects) + + for h := range obtainedObjects { + if !expectedObjects[h] { + c.Errorf("obtained unexpected object: %s", h) + } + } + + for h := range expectedObjects { + if !obtainedObjects[h] { + c.Errorf("missing object: %s", h) + } + } +} |