From b91db68056b65ccf2c41547440edb835d4ecf55d Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 19 Jan 2015 00:26:11 +0000 Subject: [PATCH] update pinning to new semantics, and fix a couple bugs --- core/commands/add.go | 5 +++ core/commands/pin.go | 78 ++----------------------------------------- core/commands/repo.go | 2 +- core/repo/pinning.go | 70 ++++++++++++++++++++++++++++++++++++++ pin/pin.go | 25 ++++++++++---- pin/pin_test.go | 4 +-- 6 files changed, 100 insertions(+), 84 deletions(-) create mode 100644 core/repo/pinning.go diff --git a/core/commands/add.go b/core/commands/add.go index 1d18c7882..e50805dc4 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -122,6 +122,11 @@ func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) { dagnodes = append(dagnodes, node) } + err := n.Pinning.Flush() + if err != nil { + return nil, err + } + return dagnodes, nil } diff --git a/core/commands/pin.go b/core/commands/pin.go index 4b59741d2..a69b750c9 100644 --- a/core/commands/pin.go +++ b/core/commands/pin.go @@ -6,8 +6,7 @@ import ( "io" cmds "github.com/jbenet/go-ipfs/commands" - "github.com/jbenet/go-ipfs/core" - "github.com/jbenet/go-ipfs/merkledag" + corerepo "github.com/jbenet/go-ipfs/core/repo" u "github.com/jbenet/go-ipfs/util" ) @@ -58,21 +57,11 @@ on disk. recursive = false } - nodes, err := pin(n, req.Arguments(), recursive) + added, err := corerepo.Pin(n, req.Arguments(), recursive) if err != nil { return nil, err } - var added []u.Key - for _, node := range nodes { - k, err := node.Key() - if err != nil { - return nil, err - } - added = append(added, k) - } - - // TODO: create some output to show what got pinned return &PinOutput{added}, nil }, Marshalers: cmds.MarshalerMap{ @@ -122,20 +111,11 @@ collected if needed. recursive = false // default } - nodes, err := unpin(n, req.Arguments(), recursive) + removed, err := corerepo.Unpin(n, req.Arguments(), recursive) if err != nil { return nil, err } - var removed []u.Key - for _, node := range nodes { - k, err := node.Key() - if err != nil { - return nil, err - } - removed = append(removed, k) - } - return &PinOutput{removed}, nil }, Marshalers: cmds.MarshalerMap{ @@ -215,55 +195,3 @@ Use --type= to specify the type of pinned keys to list. Valid values are: cmds.Text: KeyListTextMarshaler, }, } - -func pin(n *core.IpfsNode, paths []string, recursive bool) ([]*merkledag.Node, error) { - - dagnodes := make([]*merkledag.Node, 0) - for _, path := range paths { - dagnode, err := n.Resolver.ResolvePath(path) - if err != nil { - return nil, fmt.Errorf("pin error: %v", err) - } - dagnodes = append(dagnodes, dagnode) - } - - for _, dagnode := range dagnodes { - err := n.Pinning.Pin(dagnode, recursive) - if err != nil { - return nil, fmt.Errorf("pin: %v", err) - } - } - - err := n.Pinning.Flush() - if err != nil { - return nil, err - } - - return dagnodes, nil -} - -func unpin(n *core.IpfsNode, paths []string, recursive bool) ([]*merkledag.Node, error) { - - dagnodes := make([]*merkledag.Node, 0) - for _, path := range paths { - dagnode, err := n.Resolver.ResolvePath(path) - if err != nil { - return nil, err - } - dagnodes = append(dagnodes, dagnode) - } - - for _, dagnode := range dagnodes { - k, _ := dagnode.Key() - err := n.Pinning.Unpin(k, recursive) - if err != nil { - return nil, err - } - } - - err := n.Pinning.Flush() - if err != nil { - return nil, err - } - return dagnodes, nil -} diff --git a/core/commands/repo.go b/core/commands/repo.go index 2230cb5db..314d034d7 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -3,10 +3,10 @@ package commands import ( "bytes" "fmt" - "io" cmds "github.com/jbenet/go-ipfs/commands" "github.com/jbenet/go-ipfs/core" u "github.com/jbenet/go-ipfs/util" + "io" ) var RepoCmd = &cmds.Command{ diff --git a/core/repo/pinning.go b/core/repo/pinning.go new file mode 100644 index 000000000..4bb3175ee --- /dev/null +++ b/core/repo/pinning.go @@ -0,0 +1,70 @@ +package corerepo + +import ( + "fmt" + + "github.com/jbenet/go-ipfs/core" + "github.com/jbenet/go-ipfs/merkledag" + u "github.com/jbenet/go-ipfs/util" +) + +func Pin(n *core.IpfsNode, paths []string, recursive bool) ([]u.Key, error) { + + dagnodes := make([]*merkledag.Node, 0) + for _, path := range paths { + dagnode, err := n.Resolver.ResolvePath(path) + if err != nil { + return nil, fmt.Errorf("pin error: %v", err) + } + dagnodes = append(dagnodes, dagnode) + } + + var out []u.Key + for _, dagnode := range dagnodes { + k, err := dagnode.Key() + if err != nil { + return nil, err + } + + err = n.Pinning.Pin(dagnode, recursive) + if err != nil { + return nil, fmt.Errorf("pin: %v", err) + } + out = append(out, k) + } + + err := n.Pinning.Flush() + if err != nil { + return nil, err + } + + return out, nil +} + +func Unpin(n *core.IpfsNode, paths []string, recursive bool) ([]u.Key, error) { + + dagnodes := make([]*merkledag.Node, 0) + for _, path := range paths { + dagnode, err := n.Resolver.ResolvePath(path) + if err != nil { + return nil, err + } + dagnodes = append(dagnodes, dagnode) + } + + var unpinned []u.Key + for _, dagnode := range dagnodes { + k, _ := dagnode.Key() + err := n.Pinning.Unpin(k) + if err != nil { + return nil, err + } + unpinned = append(unpinned, k) + } + + err := n.Pinning.Flush() + if err != nil { + return nil, err + } + return unpinned, nil +} diff --git a/pin/pin.go b/pin/pin.go index 32b85a9d7..0ce754103 100644 --- a/pin/pin.go +++ b/pin/pin.go @@ -25,12 +25,13 @@ const ( Recursive PinMode = iota Direct Indirect + NotPinned ) type Pinner interface { IsPinned(util.Key) bool Pin(*mdag.Node, bool) error - Unpin(util.Key, bool) error + Unpin(util.Key) error Flush() error GetManual() ManualPinner DirectKeys() []util.Key @@ -90,6 +91,10 @@ func (p *pinner) Pin(node *mdag.Node, recurse bool) error { return nil } + if p.directPin.HasKey(k) { + p.directPin.RemoveBlock(k) + } + p.recursePin.AddBlock(k) err := p.pinLinks(node) @@ -97,16 +102,19 @@ func (p *pinner) Pin(node *mdag.Node, recurse bool) error { return err } } else { + if p.recursePin.HasKey(k) { + return errors.New("Key already pinned recursively.") + } p.directPin.AddBlock(k) } return nil } -// Unpin a given key with optional recursive unpinning -func (p *pinner) Unpin(k util.Key, recurse bool) error { +// Unpin a given key +func (p *pinner) Unpin(k util.Key) error { p.lock.Lock() defer p.lock.Unlock() - if recurse { + if p.recursePin.HasKey(k) { p.recursePin.RemoveBlock(k) node, err := p.dserv.Get(k) if err != nil { @@ -114,9 +122,14 @@ func (p *pinner) Unpin(k util.Key, recurse bool) error { } return p.unpinLinks(node) + } else if p.directPin.HasKey(k) { + p.directPin.RemoveBlock(k) + return nil + } else if p.indirPin.HasKey(k) { + return errors.New("Cannot unpin indirectly pinned block.") + } else { + return errors.New("Given key was not pinned.") } - p.directPin.RemoveBlock(k) - return nil } func (p *pinner) unpinLinks(node *mdag.Node) error { diff --git a/pin/pin_test.go b/pin/pin_test.go index 623983a34..3a93bdf74 100644 --- a/pin/pin_test.go +++ b/pin/pin_test.go @@ -100,8 +100,8 @@ func TestPinnerBasic(t *testing.T) { t.Fatal("pinned node not found.") } - // Test recursive unpin - err = p.Unpin(dk, true) + // Test unpin + err = p.Unpin(dk) if err != nil { t.Fatal(err) }