From f0addb4319d174f530d233b4bfd3ae4484cb67de Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 8 May 2019 21:40:17 -0700 Subject: [PATCH] pin: don't walk all pinned blocks when removing a non-existent pin We do this _just_ to make the error nicer but it's really slow. Additionally, we do it while holding the pin lock, blocking all other pin operations. fixes #6295 License: MIT Signed-off-by: Steven Allen --- pin/pin.go | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/pin/pin.go b/pin/pin.go index 24dbf4653..8df21ee1c 100644 --- a/pin/pin.go +++ b/pin/pin.go @@ -263,32 +263,24 @@ func (p *pinner) Pin(ctx context.Context, node ipld.Node, recurse bool) error { } // ErrNotPinned is returned when trying to unpin items which are not pinned. -var ErrNotPinned = fmt.Errorf("not pinned") +var ErrNotPinned = fmt.Errorf("not pinned or pinned indirectly") // Unpin a given key func (p *pinner) Unpin(ctx context.Context, c cid.Cid, recursive bool) error { p.lock.Lock() defer p.lock.Unlock() - reason, pinned, err := p.isPinnedWithType(c, Any) - if err != nil { - return err - } - if !pinned { - return ErrNotPinned - } - switch reason { - case "recursive": - if recursive { - p.recursePin.Remove(c) - return nil + if p.recursePin.Has(c) { + if !recursive { + return fmt.Errorf("%s is pinned recursively", c) } - return fmt.Errorf("%s is pinned recursively", c) - case "direct": + p.recursePin.Remove(c) + return nil + } + if p.directPin.Has(c) { p.directPin.Remove(c) return nil - default: - return fmt.Errorf("%s is pinned indirectly under %s", c, reason) } + return ErrNotPinned } func (p *pinner) isInternalPin(c cid.Cid) bool {