diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 3519385f6..9612b47cc 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -20,31 +20,27 @@ import ( type ObjectStorage struct { options Options - // deltaBaseCache is an object cache uses to cache delta's bases when - deltaBaseCache cache.Object - dir *dotgit.DotGit index map[plumbing.Hash]idxfile.Index } // NewObjectStorage creates a new ObjectStorage with the given .git directory. -func NewObjectStorage(dir *dotgit.DotGit) (ObjectStorage, error) { +func NewObjectStorage(dir *dotgit.DotGit) *ObjectStorage { return NewObjectStorageWithOptions(dir, Options{}) } // NewObjectStorageWithOptions creates a new ObjectStorage with the given .git // directory and sets its options. -func NewObjectStorageWithOptions( - dir *dotgit.DotGit, - ops Options, -) (ObjectStorage, error) { - s := ObjectStorage{ - options: ops, - deltaBaseCache: cache.NewObjectLRUDefault(), - dir: dir, +func NewObjectStorageWithOptions(dir *dotgit.DotGit, ops Options) *ObjectStorage { + s := &ObjectStorage{ + options: ops, + dir: dir, + } + if s.options.Cache == nil { + s.options.Cache = cache.NewObjectLRUDefault() } - return s, nil + return s } func (s *ObjectStorage) requireIndex() error { @@ -181,10 +177,7 @@ func (s *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (p // Create a new object storage with the DotGit(s) and check for the // required hash object. Skip when not found. for _, dg := range dotgits { - o, oe := NewObjectStorage(dg) - if oe != nil { - continue - } + o := NewObjectStorage(dg) enobj, enerr := o.EncodedObject(t, h) if enerr != nil { continue @@ -295,9 +288,13 @@ func (s *ObjectStorage) decodeObjectAt( idx idxfile.Index, offset int64, ) (plumbing.EncodedObject, error) { + if s.options.Cache == nil { + s.options.Cache = cache.NewObjectLRUDefault() + } + hash, err := idx.FindHash(offset) if err == nil { - obj, ok := s.deltaBaseCache.Get(hash) + obj, ok := s.options.Cache.Get(hash) if ok { return obj, nil } @@ -307,12 +304,7 @@ func (s *ObjectStorage) decodeObjectAt( return nil, err } - var p *packfile.Packfile - if s.deltaBaseCache != nil { - p = packfile.NewPackfileWithCache(idx, s.dir.Fs(), f, s.deltaBaseCache) - } else { - p = packfile.NewPackfile(idx, s.dir.Fs(), f) - } + p := packfile.NewPackfileWithCache(idx, s.dir.Fs(), f, s.options.Cache) return p.GetByOffset(offset) } @@ -418,7 +410,7 @@ func (s *ObjectStorage) buildPackfileIters(t plumbing.ObjectType, seen map[plumb if err != nil { return nil, err } - return newPackfileIter(s.dir.Fs(), pack, t, seen, s.index[h], s.deltaBaseCache) + return newPackfileIter(s.dir.Fs(), pack, t, seen, s.index[h], s.options.Cache) }, }, nil } diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go index b1408b7c2..9331a232d 100644 --- a/storage/filesystem/object_test.go +++ b/storage/filesystem/object_test.go @@ -26,8 +26,7 @@ var _ = Suite(&FsSuite{}) func (s *FsSuite) TestGetFromObjectFile(c *C) { fs := fixtures.ByTag(".git").ByTag("unpacked").One().DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - c.Assert(err, IsNil) + o := NewObjectStorage(dotgit.New(fs)) expected := plumbing.NewHash("f3dfe29d268303fc6e1bbce268605fc99573406e") obj, err := o.EncodedObject(plumbing.AnyObject, expected) @@ -38,8 +37,7 @@ func (s *FsSuite) TestGetFromObjectFile(c *C) { func (s *FsSuite) TestGetFromPackfile(c *C) { fixtures.Basic().ByTag(".git").Test(c, func(f *fixtures.Fixture) { fs := f.DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - c.Assert(err, IsNil) + o := NewObjectStorage(dotgit.New(fs)) expected := plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5") obj, err := o.EncodedObject(plumbing.AnyObject, expected) @@ -50,8 +48,7 @@ func (s *FsSuite) TestGetFromPackfile(c *C) { func (s *FsSuite) TestGetFromPackfileMultiplePackfiles(c *C) { fs := fixtures.ByTag(".git").ByTag("multi-packfile").One().DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - c.Assert(err, IsNil) + o := NewObjectStorage(dotgit.New(fs)) expected := plumbing.NewHash("8d45a34641d73851e01d3754320b33bb5be3c4d3") obj, err := o.getFromPackfile(expected, false) @@ -67,8 +64,7 @@ func (s *FsSuite) TestGetFromPackfileMultiplePackfiles(c *C) { func (s *FsSuite) TestIter(c *C) { fixtures.ByTag(".git").ByTag("packfile").Test(c, func(f *fixtures.Fixture) { fs := f.DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - c.Assert(err, IsNil) + o := NewObjectStorage(dotgit.New(fs)) iter, err := o.IterEncodedObjects(plumbing.AnyObject) c.Assert(err, IsNil) @@ -88,8 +84,7 @@ func (s *FsSuite) TestIterWithType(c *C) { fixtures.ByTag(".git").Test(c, func(f *fixtures.Fixture) { for _, t := range objectTypes { fs := f.DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - c.Assert(err, IsNil) + o := NewObjectStorage(dotgit.New(fs)) iter, err := o.IterEncodedObjects(t) c.Assert(err, IsNil) @@ -271,10 +266,7 @@ func BenchmarkGetObjectFromPackfile(b *testing.B) { for _, f := range fixtures.Basic() { b.Run(f.URL, func(b *testing.B) { fs := f.DotGit() - o, err := NewObjectStorage(dotgit.New(fs)) - if err != nil { - b.Fatal(err) - } + o := NewObjectStorage(dotgit.New(fs)) for i := 0; i < b.N; i++ { expected := plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5") diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go index 25b3653c0..cd16cc1f1 100644 --- a/storage/filesystem/storage.go +++ b/storage/filesystem/storage.go @@ -2,6 +2,7 @@ package filesystem import ( + "gopkg.in/src-d/go-git.v4/plumbing/cache" "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-billy.v4" @@ -24,6 +25,9 @@ type Storage struct { // Options holds configuration for the storage. type Options struct { + // Cache is an object cache used to cache deltas. + Cache cache.Object + // ExclusiveAccess means that the filesystem is not modified externally // while the repo is open. ExclusiveAccess bool @@ -44,16 +48,11 @@ func NewStorageWithOptions( } dir := dotgit.NewWithOptions(fs, dirOps) - o, err := NewObjectStorageWithOptions(dir, ops) - if err != nil { - return nil, err - } - return &Storage{ fs: fs, dir: dir, - ObjectStorage: o, + ObjectStorage: ObjectStorage{options: ops, dir: dir}, ReferenceStorage: ReferenceStorage{dir: dir}, IndexStorage: IndexStorage{dir: dir}, ShallowStorage: ShallowStorage{dir: dir}, @@ -67,6 +66,7 @@ func (s *Storage) Filesystem() billy.Filesystem { return s.fs } +// Init initializes .git directory func (s *Storage) Init() error { return s.dir.Initialize() }