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 <steven@stebalien.com>
Steven Allen committed
May 8, 2019 at 21:40 UTC
f0addb4319d174f530d233b4bfd3ae4484cb67de
1 file changed
+9
-17
pin/pin.go
+9
-17
@@ -263,32 +263,24 @@ func (p *pinner) Pin(ctx context.Context, node ipld.Node, recurse bool) error {
263
}
264
265
// ErrNotPinned is returned when trying to unpin items which are not pinned.
266
-var ErrNotPinned = fmt.Errorf("not pinned")
266
+var ErrNotPinned = fmt.Errorf("not pinned or pinned indirectly")
267
268
// Unpin a given key
269
func (p *pinner) Unpin(ctx context.Context, c cid.Cid, recursive bool) error {
270
p.lock.Lock()
271
defer p.lock.Unlock()
272
- reason, pinned, err := p.isPinnedWithType(c, Any)
273
- if err != nil {
274
- return err
275
- }
276
- if !pinned {
277
- return ErrNotPinned
278
- }
279
- switch reason {
280
- case "recursive":
281
- if recursive {
282
- p.recursePin.Remove(c)
283
- return nil
272
+ if p.recursePin.Has(c) {
273
+ if !recursive {
274
+ return fmt.Errorf("%s is pinned recursively", c)
275
}
285
- return fmt.Errorf("%s is pinned recursively", c)
286
- case "direct":
276
+ p.recursePin.Remove(c)
277
+ return nil
278
+ }
279
+ if p.directPin.Has(c) {
280
p.directPin.Remove(c)
281
return nil
289
- default:
290
- return fmt.Errorf("%s is pinned indirectly under %s", c, reason)
282
}
283
+ return ErrNotPinned
284
}
285
286
func (p *pinner) isInternalPin(c cid.Cid) bool {