aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Stribling <strib@alum.mit.edu>2017-09-22 21:14:17 -0700
committerJeremy Stribling <strib@alum.mit.edu>2017-11-29 11:01:41 -0800
commitaa092f5474da3e9c3ff4f40b88849726b645f39f (patch)
tree08655a5576a113c2946b5eac2ca801b3f5eece6f
parent2de4f034288bac895b0a87dcfb5cc3a2f9026f43 (diff)
downloadgo-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.go9
-rw-r--r--storage/filesystem/object.go26
-rw-r--r--storage/memory/storage.go8
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) {