@cryptotaxi247 / kubo / commits / 16c4d8cdc

addressing comments from CR

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Jul 10, 2015 at 10:49 UTC 16c4d8cdcbfd3aaad06580d223aa2da503f6933d
4 files changed +115 -39
pin/gc/gc.go
+1 -1
@@ -100,7 +100,7 @@ func ColoredSet(pn pin.Pinner, ds dag.DAGService) (key.KeySet, error) {
100 gcs.Add(k)
101 }
102
103 - err = Color(ds, gcs, pn.InternalPins())
103 + err = Descendants(ds, gcs, pn.InternalPins())
104 if err != nil {
105 return nil, err
106 }
pin/pin.go
+55 -5
@@ -35,7 +35,7 @@ const (
35 )
36
37 type Pinner interface {
38 - IsPinned(key.Key) bool
38 + IsPinned(key.Key) (string, bool, error)
39 Pin(context.Context, *mdag.Node, bool) error
40 Unpin(context.Context, key.Key, bool) error
41
@@ -147,12 +147,38 @@ func (p *pinner) isInternalPin(key key.Key) bool {
147 }
148
149 // IsPinned returns whether or not the given key is pinned
150 -func (p *pinner) IsPinned(key key.Key) bool {
150 +// and an explanation of why its pinned
151 +func (p *pinner) IsPinned(k key.Key) (string, bool, error) {
152 p.lock.RLock()
153 defer p.lock.RUnlock()
153 - return p.recursePin.HasKey(key) ||
154 - p.directPin.HasKey(key) ||
155 - p.isInternalPin(key)
154 + if p.recursePin.HasKey(k) {
155 + return "recursive", true, nil
156 + }
157 + if p.directPin.HasKey(k) {
158 + return "direct", true, nil
159 + }
160 + if p.isInternalPin(k) {
161 + return "internal", true, nil
162 + }
163 +
164 + for _, rk := range p.recursePin.GetKeys() {
165 + ss := &searchSet{target: k}
166 +
167 + rnd, err := p.dserv.Get(context.Background(), rk)
168 + if err != nil {
169 + return "", false, err
170 + }
171 +
172 + err = mdag.EnumerateChildren(context.Background(), p.dserv, rnd, ss)
173 + if err != nil {
174 + return "", false, err
175 + }
176 +
177 + if ss.found {
178 + return rk.B58String(), true, nil
179 + }
180 + }
181 + return "", false, nil
182 }
183
184 func (p *pinner) RemovePinWithMode(key key.Key, mode PinMode) {
@@ -308,3 +334,27 @@ func (p *pinner) PinWithMode(k key.Key, mode PinMode) {
334 p.directPin.AddBlock(k)
335 }
336 }
337 +
338 +// searchSet implements key.KeySet in
339 +type searchSet struct {
340 + target key.Key
341 + found bool
342 +}
343 +
344 +func (ss *searchSet) Add(k key.Key) {
345 + if ss.target == k {
346 + ss.found = true
347 + }
348 +}
349 +
350 +func (ss *searchSet) Has(k key.Key) bool {
351 + // returning true to all Has queries will cause EnumerateChildren to return
352 + // almost immediately
353 + return ss.found
354 +}
355 +
356 +func (ss *searchSet) Keys() []key.Key {
357 + return nil
358 +}
359 +
360 +func (ss *searchSet) Remove(key.Key) {}
pin/pin_test.go
+59 -18
@@ -24,6 +24,17 @@ func randNode() (*mdag.Node, key.Key) {
24 return nd, k
25 }
26
27 +func assertPinned(t *testing.T, p Pinner, k key.Key, failmsg string) {
28 + _, pinned, err := p.IsPinned(k)
29 + if err != nil {
30 + t.Fatal(err)
31 + }
32 +
33 + if !pinned {
34 + t.Fatal(failmsg)
35 + }
36 +}
37 +
38 func TestPinnerBasic(t *testing.T) {
39 ctx := context.Background()
40
@@ -48,13 +59,11 @@ func TestPinnerBasic(t *testing.T) {
59 t.Fatal(err)
60 }
61
51 - if !p.IsPinned(ak) {
52 - t.Fatal("Failed to find key")
53 - }
62 + assertPinned(t, p, ak, "Failed to find key")
63
64 // create new node c, to be indirectly pinned through b
65 c, _ := randNode()
57 - _, err = dserv.Add(c)
66 + ck, err := dserv.Add(c)
67 if err != nil {
68 t.Fatal(err)
69 }
@@ -82,10 +91,10 @@ func TestPinnerBasic(t *testing.T) {
91 t.Fatal(err)
92 }
93
94 + assertPinned(t, p, ck, "child of recursively pinned node not found")
95 +
96 bk, _ := b.Key()
86 - if !p.IsPinned(bk) {
87 - t.Fatal("Recursively pinned node not found..")
88 - }
97 + assertPinned(t, p, bk, "Recursively pinned node not found..")
98
99 d, _ := randNode()
100 d.AddNodeLink("a", a)
@@ -107,9 +116,7 @@ func TestPinnerBasic(t *testing.T) {
116 }
117
118 dk, _ := d.Key()
110 - if !p.IsPinned(dk) {
111 - t.Fatal("pinned node not found.")
112 - }
119 + assertPinned(t, p, dk, "pinned node not found.")
120
121 // Test recursive unpin
122 err = p.Unpin(ctx, dk, true)
@@ -128,14 +135,10 @@ func TestPinnerBasic(t *testing.T) {
135 }
136
137 // Test directly pinned
131 - if !np.IsPinned(ak) {
132 - t.Fatal("Could not find pinned node!")
133 - }
138 + assertPinned(t, np, ak, "Could not find pinned node!")
139
140 // Test recursively pinned
136 - if !np.IsPinned(bk) {
137 - t.Fatal("could not find recursively pinned node")
138 - }
141 + assertPinned(t, np, bk, "could not find recursively pinned node")
142 }
143
144 func TestDuplicateSemantics(t *testing.T) {
@@ -187,8 +190,46 @@ func TestFlush(t *testing.T) {
190 if err := p.Flush(); err != nil {
191 t.Fatal(err)
192 }
190 - if !p.IsPinned(k) {
191 - t.Fatal("expected key to still be pinned")
193 + assertPinned(t, p, k, "expected key to still be pinned")
194 +}
195 +
196 +func TestPinRecursiveFail(t *testing.T) {
197 + ctx := context.Background()
198 + dstore := dssync.MutexWrap(ds.NewMapDatastore())
199 + bstore := blockstore.NewBlockstore(dstore)
200 + bserv, err := bs.New(bstore, offline.Exchange(bstore))
201 + if err != nil {
202 + t.Fatal(err)
203 + }
204 +
205 + dserv := mdag.NewDAGService(bserv)
206 +
207 + p := NewPinner(dstore, dserv)
208 +
209 + a, _ := randNode()
210 + b, _ := randNode()
211 + err = a.AddNodeLinkClean("child", b)
212 + if err != nil {
213 + t.Fatal(err)
214 + }
215 +
216 + // Note: this isnt a time based test, we expect the pin to fail
217 + mctx, _ := context.WithTimeout(ctx, time.Millisecond)
218 + err = p.Pin(mctx, a, true)
219 + if err == nil {
220 + t.Fatal("should have failed to pin here")
221 + }
222 +
223 + _, err = dserv.Add(b)
224 + if err != nil {
225 + t.Fatal(err)
226 + }
227 +
228 + // this one is time based... but shouldnt cause any issues
229 + mctx, _ = context.WithTimeout(ctx, time.Second)
230 + err = p.Pin(mctx, a, true)
231 + if err != nil {
232 + t.Fatal(err)
233 }
234 }
235
unixfs/mod/dagmodifier_test.go
-15
@@ -10,7 +10,6 @@ import (
10
11 "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
12 "github.com/ipfs/go-ipfs/blocks/blockstore"
13 - key "github.com/ipfs/go-ipfs/blocks/key"
13 bs "github.com/ipfs/go-ipfs/blockservice"
14 "github.com/ipfs/go-ipfs/exchange/offline"
15 imp "github.com/ipfs/go-ipfs/importer"
@@ -564,20 +563,6 @@ func TestCorrectPinning(t *testing.T) {
563
564 }
565
567 -func enumerateChildren(t *testing.T, nd *mdag.Node, ds mdag.DAGService) []key.Key {
568 - var out []key.Key
569 - for _, lnk := range nd.Links {
570 - out = append(out, key.Key(lnk.Hash))
571 - child, err := lnk.GetNode(context.Background(), ds)
572 - if err != nil {
573 - t.Fatal(err)
574 - }
575 - children := enumerateChildren(t, child, ds)
576 - out = append(out, children...)
577 - }
578 - return out
579 -}
580 -
566 func BenchmarkDagmodWrite(b *testing.B) {
567 b.StopTimer()
568 dserv, pins := getMockDagServ(b)