From 1e1315d5e587d481e73e295dd18e50026af48c79 Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Thu, 11 Oct 2018 16:24:25 -0700 Subject: object: get object size without reading whole object Signed-off-by: Jeremy Stribling --- plumbing/format/packfile/packfile.go | 16 ++++++++++++++++ plumbing/storer/object.go | 2 ++ plumbing/storer/object_test.go | 10 ++++++++++ 3 files changed, 28 insertions(+) (limited to 'plumbing') diff --git a/plumbing/format/packfile/packfile.go b/plumbing/format/packfile/packfile.go index 852a834..dbd5d4b 100644 --- a/plumbing/format/packfile/packfile.go +++ b/plumbing/format/packfile/packfile.go @@ -90,6 +90,22 @@ func (p *Packfile) GetByOffset(o int64) (plumbing.EncodedObject, error) { return p.nextObject() } +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/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 { -- cgit From 5c471c34813577a420c1a5af61dd855f70badce1 Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Thu, 11 Oct 2018 16:28:19 -0700 Subject: tree: add a Size() method for getting plaintext size Without reading the entire object into memory. Signed-off-by: Jeremy Stribling --- plumbing/object/tree.go | 11 +++++++++++ plumbing/object/tree_test.go | 6 ++++++ 2 files changed, 17 insertions(+) (limited to 'plumbing') 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 { -- cgit From 6faf286b97ff2e13fbdaf2c6179f8aef36b4498c Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Mon, 15 Oct 2018 10:17:37 -0700 Subject: packfile: add comment on GetSizeByOffset Suggested by mcuadros. Issue: src-d/go-git#982 Signed-off-by: Jeremy Stribling --- plumbing/format/packfile/packfile.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plumbing') diff --git a/plumbing/format/packfile/packfile.go b/plumbing/format/packfile/packfile.go index dbd5d4b..0d13066 100644 --- a/plumbing/format/packfile/packfile.go +++ b/plumbing/format/packfile/packfile.go @@ -90,6 +90,8 @@ 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) { -- cgit