diff options
author | Filip Navara <filip.navara@gmail.com> | 2019-04-23 10:50:20 +0200 |
---|---|---|
committer | Filip Navara <filip.navara@gmail.com> | 2019-04-23 10:50:20 +0200 |
commit | c215c50159f40e97a1030f7bf87b3ca00f968e54 (patch) | |
tree | 9087bbf0a158e8fc12f8a5ba34a885a3be5c7c62 /plumbing/format/packfile | |
parent | 553fba6a738578058d4afc1897bd210d90bb0474 (diff) | |
download | go-git-c215c50159f40e97a1030f7bf87b3ca00f968e54.tar.gz |
Avoid filling up the object cache from Packfile.GetByType with typ != plumbing.AnyObject
Signed-off-by: Filip Navara <filip.navara@gmail.com>
Diffstat (limited to 'plumbing/format/packfile')
-rw-r--r-- | plumbing/format/packfile/packfile.go | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/plumbing/format/packfile/packfile.go b/plumbing/format/packfile/packfile.go index 3d32b36..55755e4 100644 --- a/plumbing/format/packfile/packfile.go +++ b/plumbing/format/packfile/packfile.go @@ -83,10 +83,8 @@ func (p *Packfile) Get(h plumbing.Hash) (plumbing.EncodedObject, error) { // offset. func (p *Packfile) GetByOffset(o int64) (plumbing.EncodedObject, error) { hash, err := p.FindHash(o) - if err == nil { - if obj, ok := p.deltaBaseCache.Get(hash); ok { - return obj, nil - } + if err != nil { + return nil, err } return p.objectAtOffset(o, hash) @@ -180,10 +178,16 @@ func (p *Packfile) getObjectType(h *ObjectHeader) (typ plumbing.ObjectType, err err = ErrInvalidObject.AddDetails("type %q", h.Type) } + p.offsetToType[h.Offset] = typ + return } func (p *Packfile) objectAtOffset(offset int64, hash plumbing.Hash) (plumbing.EncodedObject, error) { + if obj, ok := p.deltaBaseCache.Get(hash); ok { + return obj, nil + } + h, err := p.objectHeaderAtOffset(offset) if err != nil { if err == io.EOF || isInvalid(err) { @@ -192,6 +196,12 @@ func (p *Packfile) objectAtOffset(offset int64, hash plumbing.Hash) (plumbing.En return nil, err } + return p.getNextObjectLazy(h, hash) +} + +func (p *Packfile) getNextObjectLazy(h *ObjectHeader, hash plumbing.Hash) (plumbing.EncodedObject, error) { + var err error + // If we have no filesystem, we will return a MemoryObject instead // of an FSObject. if p.fs == nil { @@ -303,6 +313,8 @@ func (p *Packfile) getNextObject(h *ObjectHeader) (plumbing.EncodedObject, error return nil, err } + p.offsetToType[h.Offset] = obj.Type() + return obj, nil } @@ -361,19 +373,14 @@ func (p *Packfile) fillOFSDeltaObjectContent(obj plumbing.EncodedObject, offset } func (p *Packfile) fillOFSDeltaObjectContentWithBuffer(obj plumbing.EncodedObject, offset int64, buf *bytes.Buffer) error { - var err error - var base plumbing.EncodedObject - var ok bool hash, err := p.FindHash(offset) - if err == nil { - base, ok = p.cacheGet(hash) + if err != nil { + return err } - if !ok { - base, err = p.objectAtOffset(offset, hash) - if err != nil { - return err - } + base, err := p.objectAtOffset(offset, hash) + if err != nil { + return err } obj.SetType(base.Type()) @@ -475,14 +482,32 @@ func (i *objectIter) Next() (plumbing.EncodedObject, error) { return nil, err } + if i.typ != plumbing.AnyObject { + if typ, ok := i.p.offsetToType[int64(e.Offset)]; ok { + if typ != i.typ { + continue + } + } else { + h, err := i.p.objectHeaderAtOffset(int64(e.Offset)) + if err != nil { + return nil, err + } + + typ, err := i.p.getObjectType(h) + if err == nil && typ != i.typ { + continue + } + + return i.p.getNextObjectLazy(h, e.Hash) + } + } + obj, err := i.p.GetByOffset(int64(e.Offset)) if err != nil { return nil, err } - if i.typ == plumbing.AnyObject || obj.Type() == i.typ { - return obj, nil - } + return obj, nil } } |