aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2018-10-16 10:11:39 +0200
committerGitHub <noreply@github.com>2018-10-16 10:11:39 +0200
commit41d6f2c31e68a9fdcbff4a3da8c40247f1293cc9 (patch)
tree655fed8324e58a6ba44ef45f1bb2e090abe26451 /plumbing
parent8153e040f68da6002096ef177a11510f4fb06769 (diff)
parent6faf286b97ff2e13fbdaf2c6179f8aef36b4498c (diff)
downloadgo-git-41d6f2c31e68a9fdcbff4a3da8c40247f1293cc9.tar.gz
Merge pull request #982 from keybase/strib/gh-KBFS-3474-object-sizes
tree: add a Size() method for getting plaintext size
Diffstat (limited to 'plumbing')
-rw-r--r--plumbing/format/packfile/packfile.go18
-rw-r--r--plumbing/object/tree.go11
-rw-r--r--plumbing/object/tree_test.go6
-rw-r--r--plumbing/storer/object.go2
-rw-r--r--plumbing/storer/object_test.go10
5 files changed, 47 insertions, 0 deletions
diff --git a/plumbing/format/packfile/packfile.go b/plumbing/format/packfile/packfile.go
index 852a834..0d13066 100644
--- a/plumbing/format/packfile/packfile.go
+++ b/plumbing/format/packfile/packfile.go
@@ -90,6 +90,24 @@ func (p *Packfile) GetByOffset(o int64) (plumbing.EncodedObject, error) {
return p.nextObject()
}
+// GetSizeByOffset retrieves the size of the encoded object from the
+// packfile with the given offset.
+func (p *Packfile) GetSizeByOffset(o int64) (size int64, err error) {
+ if _, err := p.s.SeekFromStart(o); err != nil {
+ if err == io.EOF || isInvalid(err) {
+ return 0, plumbing.ErrObjectNotFound
+ }
+
+ return 0, err
+ }
+
+ h, err := p.nextObjectHeader()
+ if err != nil {
+ return 0, err
+ }
+ return h.Length, nil
+}
+
func (p *Packfile) nextObjectHeader() (*ObjectHeader, error) {
h, err := p.s.NextObjectHeader()
p.s.pendingObject = nil
diff --git a/plumbing/object/tree.go b/plumbing/object/tree.go
index c36a137..78d61a1 100644
--- a/plumbing/object/tree.go
+++ b/plumbing/object/tree.go
@@ -87,6 +87,17 @@ func (t *Tree) File(path string) (*File, error) {
return NewFile(path, e.Mode, blob), nil
}
+// Size returns the plaintext size of an object, without reading it
+// into memory.
+func (t *Tree) Size(path string) (int64, error) {
+ e, err := t.FindEntry(path)
+ if err != nil {
+ return 0, ErrEntryNotFound
+ }
+
+ return t.s.EncodedObjectSize(e.Hash)
+}
+
// Tree returns the tree identified by the `path` argument.
// The path is interpreted as relative to the tree receiver.
func (t *Tree) Tree(path string) (*Tree, error) {
diff --git a/plumbing/object/tree_test.go b/plumbing/object/tree_test.go
index 7366421..889c63a 100644
--- a/plumbing/object/tree_test.go
+++ b/plumbing/object/tree_test.go
@@ -98,6 +98,12 @@ func (s *TreeSuite) TestFileFailsWithExistingTrees(c *C) {
c.Assert(err, Equals, ErrFileNotFound)
}
+func (s *TreeSuite) TestSize(c *C) {
+ size, err := s.Tree.Size("LICENSE")
+ c.Assert(err, IsNil)
+ c.Assert(size, Equals, int64(1072))
+}
+
func (s *TreeSuite) TestFiles(c *C) {
var count int
err := s.Tree.Files().ForEach(func(f *File) error {
diff --git a/plumbing/storer/object.go b/plumbing/storer/object.go
index 92aa629..2ac9b09 100644
--- a/plumbing/storer/object.go
+++ b/plumbing/storer/object.go
@@ -40,6 +40,8 @@ type EncodedObjectStorer interface {
// HasEncodedObject returns ErrObjNotFound if the object doesn't
// exist. If the object does exist, it returns nil.
HasEncodedObject(plumbing.Hash) error
+ // EncodedObjectSize returns the plaintext size of the encoded object.
+ EncodedObjectSize(plumbing.Hash) (int64, error)
}
// DeltaObjectStorer is an EncodedObjectStorer that can return delta
diff --git a/plumbing/storer/object_test.go b/plumbing/storer/object_test.go
index 6b4fe0f..bc22f7b 100644
--- a/plumbing/storer/object_test.go
+++ b/plumbing/storer/object_test.go
@@ -141,6 +141,16 @@ func (o *MockObjectStorage) HasEncodedObject(h plumbing.Hash) error {
return plumbing.ErrObjectNotFound
}
+func (o *MockObjectStorage) EncodedObjectSize(h plumbing.Hash) (
+ size int64, err error) {
+ for _, o := range o.db {
+ if o.Hash() == h {
+ return o.Size(), nil
+ }
+ }
+ return 0, plumbing.ErrObjectNotFound
+}
+
func (o *MockObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
for _, o := range o.db {
if o.Hash() == h {