diff options
author | Jeremy Stribling <strib@alum.mit.edu> | 2017-09-22 21:14:17 -0700 |
---|---|---|
committer | Jeremy Stribling <strib@alum.mit.edu> | 2017-11-29 11:01:41 -0800 |
commit | aa092f5474da3e9c3ff4f40b88849726b645f39f (patch) | |
tree | 08655a5576a113c2946b5eac2ca801b3f5eece6f | |
parent | 2de4f034288bac895b0a87dcfb5cc3a2f9026f43 (diff) | |
download | go-git-aa092f5474da3e9c3ff4f40b88849726b645f39f.tar.gz |
plumbing: add `HasEncodedObject` method to Storer
This allows the user to check whether an object exists, without
reading all the object data from storage.
Issue: KBFS-2445
-rw-r--r-- | plumbing/storer/object_test.go | 9 | ||||
-rw-r--r-- | storage/filesystem/object.go | 26 | ||||
-rw-r--r-- | storage/memory/storage.go | 8 |
3 files changed, 43 insertions, 0 deletions
diff --git a/plumbing/storer/object_test.go b/plumbing/storer/object_test.go index da0db81..9a6959d 100644 --- a/plumbing/storer/object_test.go +++ b/plumbing/storer/object_test.go @@ -133,6 +133,15 @@ func (o *MockObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbi return plumbing.ZeroHash, nil } +func (o *MockObjectStorage) HasEncodedObject(h plumbing.Hash) error { + for _, o := range o.db { + if o.Hash() == h { + return nil + } + } + return plumbing.ErrObjectNotFound +} + func (o *MockObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) { for _, o := range o.db { if o.Hash() == h { diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 13b8ddb..34501ec 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -126,6 +126,32 @@ func (s *ObjectStorage) SetEncodedObject(o plumbing.EncodedObject) (plumbing.Has return o.Hash(), err } +// HasEncodedObject returns nil if the object exists, without actually +// reading the object data from storage. +func (s *ObjectStorage) HasEncodedObject(h plumbing.Hash) (err error) { + // Check unpacked objects + f, err := s.dir.Object(h) + if err != nil { + if !os.IsNotExist(err) { + return err + } + // Fall through to check packed objects. + } else { + defer ioutil.CheckClose(f, &err) + return nil + } + + // Check packed objects. + if err := s.requireIndex(); err != nil { + return err + } + _, _, offset := s.findObjectInPackfile(h) + if offset == -1 { + return plumbing.ErrObjectNotFound + } + return nil +} + // EncodedObject returns the object with the given hash, by searching for it in // the packfile and the git object directories. func (s *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) { diff --git a/storage/memory/storage.go b/storage/memory/storage.go index 2d1a4b6..c76d163 100644 --- a/storage/memory/storage.go +++ b/storage/memory/storage.go @@ -115,6 +115,14 @@ func (o *ObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.H return h, nil } +func (o *ObjectStorage) HasEncodedObject(h plumbing.Hash) (err error) { + _, ok := o.Objects[h] + if !ok { + return plumbing.ErrObjectNotFound + } + return nil +} + func (o *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) { obj, ok := o.Objects[h] if !ok || (plumbing.AnyObject != t && obj.Type() != t) { |