aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavi Fontan <jfontan@gmail.com>2019-01-30 18:50:35 +0100
committerJavi Fontan <jfontan@gmail.com>2019-01-30 18:58:38 +0100
commit51b01ef90c03c2f83126eb339723d7b7e7a6a245 (patch)
tree5af72223dcc5ff071016e16cba0967f3fa1d0293
parent434611b74cb54538088c6aeed4ed27d3044064fa (diff)
downloadgo-git-51b01ef90c03c2f83126eb339723d7b7e7a6a245.tar.gz
storage/filesystem: check file object before using cache
If the cache is shared between several repositories getFromUnpacked can erroneously return an object from other repository. This decreases performance a little bit as there's an extra fs operation when the object is in the cache but is correct when the cache is shared. Signed-off-by: Javi Fontan <jfontan@gmail.com>
-rw-r--r--storage/filesystem/object.go9
-rw-r--r--storage/filesystem/object_test.go17
2 files changed, 21 insertions, 5 deletions
diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go
index 85bb798..3eb62a2 100644
--- a/storage/filesystem/object.go
+++ b/storage/filesystem/object.go
@@ -307,10 +307,6 @@ func (s *ObjectStorage) DeltaObject(t plumbing.ObjectType,
}
func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedObject, err error) {
- if cacheObj, found := s.objectCache.Get(h); found {
- return cacheObj, nil
- }
-
f, err := s.dir.Object(h)
if err != nil {
if os.IsNotExist(err) {
@@ -319,9 +315,12 @@ func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedOb
return nil, err
}
-
defer ioutil.CheckClose(f, &err)
+ if cacheObj, found := s.objectCache.Get(h); found {
+ return cacheObj, nil
+ }
+
obj = s.NewEncodedObject()
r, err := objfile.NewReader(f)
if err != nil {
diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go
index 77eb31d..5cfb227 100644
--- a/storage/filesystem/object_test.go
+++ b/storage/filesystem/object_test.go
@@ -297,6 +297,23 @@ func (s *FsSuite) TestPackfileIterKeepDescriptors(c *C) {
})
}
+func (s *FsSuite) TestGetFromObjectFileSharedCache(c *C) {
+ f1 := fixtures.ByTag("worktree").One().DotGit()
+ f2 := fixtures.ByTag("worktree").ByTag("submodule").One().DotGit()
+
+ ch := cache.NewObjectLRUDefault()
+ o1 := NewObjectStorage(dotgit.New(f1), ch)
+ o2 := NewObjectStorage(dotgit.New(f2), ch)
+
+ expected := plumbing.NewHash("af2d6a6954d532f8ffb47615169c8fdf9d383a1a")
+ obj, err := o1.EncodedObject(plumbing.CommitObject, expected)
+ c.Assert(err, IsNil)
+ c.Assert(obj.Hash(), Equals, expected)
+
+ obj, err = o2.EncodedObject(plumbing.CommitObject, expected)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
func BenchmarkPackfileIter(b *testing.B) {
if err := fixtures.Init(); err != nil {
b.Fatal(err)