Skip to content

Commit

Permalink
Make pin rm not try to find pinned ancestors by default
Browse files Browse the repository at this point in the history
Also make a switch to pin rm to allow old behavior.
Trying to look up pins which interfere with requested unpin
can be an extremely costly operation and typically is not
required by user.

License: MIT
Signed-off-by: Iaroslav Gridin <voker57@gmail.com>
  • Loading branch information
Voker57 committed Jan 15, 2017
1 parent ea36c38 commit 8e15b98
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 18 deletions.
9 changes: 8 additions & 1 deletion core/commands/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
},
Options: []cmds.Option{
cmds.BoolOption("recursive", "r", "Recursively unpin the object linked to by the specified object(s).").Default(true),
cmds.BoolOption("explain", "e", "Check for other pinned objects which could cause specified object(s) to be indirectly pinned").Default(false),
},
Type: PinOutput{},
Run: func(req cmds.Request, res cmds.Response) {
Expand All @@ -124,7 +125,13 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
return
}

removed, err := corerepo.Unpin(n, req.Context(), req.Arguments(), recursive)
explain, _, err := req.Option("explain").Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

removed, err := corerepo.Unpin(n, req.Context(), req.Arguments(), recursive, explain)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
Expand Down
4 changes: 2 additions & 2 deletions core/corerepo/pinning.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool)
return out, nil
}

func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]*cid.Cid, error) {
func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool, explain bool) ([]*cid.Cid, error) {

var unpinned []*cid.Cid
for _, p := range paths {
Expand All @@ -76,7 +76,7 @@ func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool

ctx, cancel := context.WithCancel(ctx)
defer cancel()
err = n.Pinning.Unpin(ctx, k, recursive)
err = n.Pinning.Unpin(ctx, k, recursive, explain)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion core/coreunix/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (adder *Adder) PinRoot() error {
}

if adder.tempRoot != nil {
err := adder.pinning.Unpin(adder.ctx, adder.tempRoot, true)
err := adder.pinning.Unpin(adder.ctx, adder.tempRoot, true, false)
if err != nil {
return err
}
Expand Down
37 changes: 24 additions & 13 deletions pin/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type Pinner interface {
IsPinned(*cid.Cid) (string, bool, error)
IsPinnedWithType(*cid.Cid, PinMode) (string, bool, error)
Pin(context.Context, node.Node, bool) error
Unpin(context.Context, *cid.Cid, bool) error
Unpin(context.Context, *cid.Cid, bool, bool) error

// Check if a set of keys are pinned, more efficient than
// calling IsPinned for each key
Expand Down Expand Up @@ -200,29 +200,40 @@ func (p *pinner) Pin(ctx context.Context, node node.Node, recurse bool) error {
var ErrNotPinned = fmt.Errorf("not pinned")

// Unpin a given key
func (p *pinner) Unpin(ctx context.Context, c *cid.Cid, recursive bool) error {
func (p *pinner) Unpin(ctx context.Context, c *cid.Cid, recursive bool, explain bool) error {
p.lock.Lock()
defer p.lock.Unlock()
reason, pinned, err := p.isPinnedWithType(c, Any)
var pinMode PinMode
if recursive {
pinMode = Recursive
} else {
pinMode = Direct
}
_, pinned, err := p.isPinnedWithType(c, pinMode)
if err != nil {
return err
}
if !pinned {
return ErrNotPinned
}
switch reason {
case "recursive":
if pinned {
if recursive {
p.recursePin.Remove(c)
return nil
} else {
p.directPin.Remove(c)
return nil
}
} else if explain {
reason, _, err := p.isPinnedWithType(c, Any)
if err != nil {
return err
}
switch reason {
case "recursive":
return fmt.Errorf("%s is pinned recursively", c)
default:
return fmt.Errorf("%s is pinned indirectly under %s", c, reason)
}
case "direct":
p.directPin.Remove(c)
return nil
default:
return fmt.Errorf("%s is pinned indirectly under %s", c, reason)
} else {
return ErrNotPinned
}
}

Expand Down
2 changes: 1 addition & 1 deletion pin/pin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func TestPinnerBasic(t *testing.T) {
assertPinned(t, p, dk, "pinned node not found.")

// Test recursive unpin
err = p.Unpin(ctx, dk, true)
err = p.Unpin(ctx, dk, true, false)
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 8e15b98

Please sign in to comment.