Commit a8df3a22 authored by Jeromy's avatar Jeromy

implement ipfs pin update

License: MIT
Signed-off-by: default avatarJeromy <jeromyj@gmail.com>
parent 566ac617
......@@ -10,6 +10,7 @@ import (
"time"
mdag "github.com/ipfs/go-ipfs/merkledag"
dutils "github.com/ipfs/go-ipfs/merkledag/utils"
ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
......@@ -86,6 +87,11 @@ type Pinner interface {
Pin(context.Context, node.Node, bool) error
Unpin(context.Context, *cid.Cid, bool) error
// Update updates a recursive pin from one cid to another
// this is more efficient than simply pinning the new one and unpinning the
// old one
Update(context.Context, *cid.Cid, *cid.Cid, bool) error
// Check if a set of keys are pinned, more efficient than
// calling IsPinned for each key
CheckIfPinned(cids ...*cid.Cid) ([]Pinned, error)
......@@ -94,6 +100,7 @@ type Pinner interface {
// care! If used improperly, garbage collection may not be
// successful.
PinWithMode(*cid.Cid, PinMode)
// RemovePinWithMode is for manually editing the pin structure.
// Use with care! If used improperly, garbage collection may not
// be successful.
......@@ -447,6 +454,26 @@ func (p *pinner) RecursiveKeys() []*cid.Cid {
return p.recursePin.Keys()
}
func (p *pinner) Update(ctx context.Context, from, to *cid.Cid, unpin bool) error {
p.lock.Lock()
defer p.lock.Unlock()
if !p.recursePin.Has(from) {
return fmt.Errorf("'from' cid was not recursively pinned already")
}
err := dutils.DiffEnumerate(ctx, p.dserv, from, to)
if err != nil {
return err
}
p.recursePin.Add(to)
if unpin {
p.recursePin.Remove(from)
}
return nil
}
// Flush encodes and writes pinner keysets to the datastore
func (p *pinner) Flush() error {
p.lock.Lock()
......
package pin
import (
"context"
"testing"
"time"
......@@ -9,7 +10,6 @@ import (
"github.com/ipfs/go-ipfs/exchange/offline"
mdag "github.com/ipfs/go-ipfs/merkledag"
context "context"
ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
dssync "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore/sync"
"gx/ipfs/QmWbjfz3u6HkAdPh34dgPchGbQjob6LXLhAeCGii2TX69n/go-ipfs-util"
......@@ -367,3 +367,36 @@ func TestPinRecursiveFail(t *testing.T) {
t.Fatal(err)
}
}
func TestPinUpdate(t *testing.T) {
dstore := dssync.MutexWrap(ds.NewMapDatastore())
bstore := blockstore.NewBlockstore(dstore)
bserv := bs.New(bstore, offline.Exchange(bstore))
dserv := mdag.NewDAGService(bserv)
p := NewPinner(dstore, dserv, dserv)
n1, c1 := randNode()
n2, c2 := randNode()
dserv.Add(n1)
dserv.Add(n2)
ctx := context.Background()
if err := p.Pin(ctx, n1, true); err != nil {
t.Fatal(err)
}
if err := p.Update(ctx, c1, c2, true); err != nil {
t.Fatal(err)
}
assertPinned(t, p, c2, "c2 should be pinned now")
assertUnpinned(t, p, c1, "c1 should no longer be pinned")
if err := p.Update(ctx, c2, c1, false); err != nil {
t.Fatal(err)
}
assertPinned(t, p, c2, "c2 should be pinned still")
assertPinned(t, p, c1, "c1 should be pinned now")
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment