@cryptotaxi247 / kubo / commits / 67c2a4ec1

make path resolver no longer require whole node for construction

License: MIT Signed-off-by: Jeromy <why@ipfs.io>

Jeromy committed Oct 19, 2016 at 10:05 UTC 67c2a4ec14a230818e0cd0052725ac001b048968
23 files changed +161 -50
core/builder.go
+1 -1
@@ -214,7 +214,7 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
214 // this is kinda sketchy and could cause data loss
215 n.Pinning = pin.NewPinner(n.Repo.Datastore(), n.DAG, internalDag)
216 }
217 - n.Resolver = &path.Resolver{DAG: n.DAG}
217 + n.Resolver = path.NewBasicResolver(n.DAG)
218
219 err = n.loadFilesRoot()
220 if err != nil {
core/commands/files/files.go
+7 -2
@@ -16,6 +16,7 @@ import (
16 mfs "github.com/ipfs/go-ipfs/mfs"
17 path "github.com/ipfs/go-ipfs/path"
18 ft "github.com/ipfs/go-ipfs/unixfs"
19 + uio "github.com/ipfs/go-ipfs/unixfs/io"
20
21 logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
22 node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
@@ -259,11 +260,15 @@ func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (node.N
260 return nil, err
261 }
262
262 - nd, err := core.Resolve(ctx, node, np)
263 + resolver := &path.Resolver{
264 + DAG: node.DAG,
265 + ResolveOnce: uio.ResolveUnixfsOnce,
266 + }
267 +
268 + nd, err := core.Resolve(ctx, node.Namesys, resolver, np)
269 if err != nil {
270 return nil, err
271 }
266 -
272 pbnd, ok := nd.(*dag.ProtoNode)
273 if !ok {
274 return nil, dag.ErrNotProtobuf
core/commands/get.go
+1 -1
@@ -64,7 +64,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
64 }
65 p := path.Path(req.Arguments()[0])
66 ctx := req.Context()
67 - dn, err := core.Resolve(ctx, node, p)
67 + dn, err := core.Resolve(ctx, node.Namesys, node.Resolver, p)
68 if err != nil {
69 res.SetError(err, cmds.ErrNormal)
70 return
core/commands/ls.go
+13 -1
@@ -11,6 +11,7 @@ import (
11 merkledag "github.com/ipfs/go-ipfs/merkledag"
12 path "github.com/ipfs/go-ipfs/path"
13 unixfs "github.com/ipfs/go-ipfs/unixfs"
14 + uio "github.com/ipfs/go-ipfs/unixfs/io"
15 unixfspb "github.com/ipfs/go-ipfs/unixfs/pb"
16
17 node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
@@ -74,7 +75,18 @@ The JSON output contains type information.
75
76 var dagnodes []node.Node
77 for _, fpath := range paths {
77 - dagnode, err := core.Resolve(req.Context(), nd, path.Path(fpath))
78 + p, err := path.ParsePath(fpath)
79 + if err != nil {
80 + res.SetError(err, cmds.ErrNormal)
81 + return
82 + }
83 +
84 + r := &path.Resolver{
85 + DAG: nd.DAG,
86 + ResolveOnce: uio.ResolveUnixfsOnce,
87 + }
88 +
89 + dagnode, err := core.Resolve(req.Context(), nd.Namesys, r, p)
90 if err != nil {
91 res.SetError(err, cmds.ErrNormal)
92 return
core/commands/object/diff.go
+2 -2
@@ -74,13 +74,13 @@ Example:
74
75 ctx := req.Context()
76
77 - obj_a, err := core.Resolve(ctx, node, pa)
77 + obj_a, err := core.Resolve(ctx, node.Namesys, node.Resolver, pa)
78 if err != nil {
79 res.SetError(err, cmds.ErrNormal)
80 return
81 }
82
83 - obj_b, err := core.Resolve(ctx, node, pb)
83 + obj_b, err := core.Resolve(ctx, node.Namesys, node.Resolver, pb)
84 if err != nil {
85 res.SetError(err, cmds.ErrNormal)
86 return
core/commands/object/object.go
+4 -4
@@ -94,7 +94,7 @@ is the raw data of the object.
94 return
95 }
96
97 - node, err := core.Resolve(req.Context(), n, fpath)
97 + node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
98 if err != nil {
99 res.SetError(err, cmds.ErrNormal)
100 return
@@ -140,7 +140,7 @@ multihash.
140 }
141
142 fpath := path.Path(req.Arguments()[0])
143 - node, err := core.Resolve(req.Context(), n, fpath)
143 + node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
144 if err != nil {
145 res.SetError(err, cmds.ErrNormal)
146 return
@@ -204,7 +204,7 @@ This command outputs data in the following encodings:
204
205 fpath := path.Path(req.Arguments()[0])
206
207 - object, err := core.Resolve(req.Context(), n, fpath)
207 + object, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
208 if err != nil {
209 res.SetError(err, cmds.ErrNormal)
210 return
@@ -277,7 +277,7 @@ var ObjectStatCmd = &cmds.Command{
277
278 fpath := path.Path(req.Arguments()[0])
279
280 - object, err := core.Resolve(req.Context(), n, fpath)
280 + object, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
281 if err != nil {
282 res.SetError(err, cmds.ErrNormal)
283 return
core/commands/object/patch.go
+5 -5
@@ -73,7 +73,7 @@ the limit will not be respected by the network.
73 return
74 }
75
76 - rootnd, err := core.Resolve(req.Context(), nd, root)
76 + rootnd, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, root)
77 if err != nil {
78 res.SetError(err, cmds.ErrNormal)
79 return
@@ -141,7 +141,7 @@ Example:
141 return
142 }
143
144 - root, err := core.Resolve(req.Context(), nd, rp)
144 + root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rp)
145 if err != nil {
146 res.SetError(err, cmds.ErrNormal)
147 return
@@ -205,7 +205,7 @@ Removes a link by the given name from root.
205 return
206 }
207
208 - root, err := core.Resolve(req.Context(), nd, rootp)
208 + root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rootp)
209 if err != nil {
210 res.SetError(err, cmds.ErrNormal)
211 return
@@ -280,7 +280,7 @@ to a file containing 'bar', and returns the hash of the new object.
280 return
281 }
282
283 - root, err := core.Resolve(req.Context(), nd, rootp)
283 + root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rootp)
284 if err != nil {
285 res.SetError(err, cmds.ErrNormal)
286 return
@@ -312,7 +312,7 @@ to a file containing 'bar', and returns the hash of the new object.
312
313 e := dagutils.NewDagEditor(rtpb, nd.DAG)
314
315 - childnd, err := core.Resolve(req.Context(), nd, childp)
315 + childnd, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, childp)
316 if err != nil {
317 res.SetError(err, cmds.ErrNormal)
318 return
core/commands/pin.go
+1 -1
@@ -277,7 +277,7 @@ func pinLsKeys(args []string, typeStr string, ctx context.Context, n *core.IpfsN
277 return nil, err
278 }
279
280 - dagNode, err := core.Resolve(ctx, n, pth)
280 + dagNode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pth)
281 if err != nil {
282 return nil, err
283 }
core/commands/publish.go
+1 -1
@@ -135,7 +135,7 @@ func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.P
135
136 if opts.verifyExists {
137 // verify the path exists
138 - _, err := core.Resolve(ctx, n, ref)
138 + _, err := core.Resolve(ctx, n.Namesys, n.Resolver, ref)
139 if err != nil {
140 return nil, err
141 }
core/commands/refs.go
+7 -2
@@ -198,8 +198,13 @@ var refsMarshallerMap = cmds.MarshalerMap{
198
199 func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]node.Node, error) {
200 objects := make([]node.Node, len(paths))
201 - for i, p := range paths {
202 - o, err := core.Resolve(ctx, n, path.Path(p))
201 + for i, sp := range paths {
202 + p, err := path.ParsePath(sp)
203 + if err != nil {
204 + return nil, err
205 + }
206 +
207 + o, err := core.Resolve(ctx, n.Namesys, n.Resolver, p)
208 if err != nil {
209 return nil, err
210 }
core/commands/resolve.go
+1 -1
@@ -99,7 +99,7 @@ Resolve the value of an IPFS DAG path:
99 return
100 }
101
102 - node, err := core.Resolve(req.Context(), n, p)
102 + node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, p)
103 if err != nil {
104 res.SetError(err, cmds.ErrNormal)
105 return
core/commands/tar.go
+1 -1
@@ -95,7 +95,7 @@ var tarCatCmd = &cmds.Command{
95 return
96 }
97
98 - root, err := core.Resolve(req.Context(), nd, p)
98 + root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, p)
99 if err != nil {
100 res.SetError(err, cmds.ErrNormal)
101 return
core/commands/unixfs/ls.go
+8 -1
@@ -12,6 +12,7 @@ import (
12 merkledag "github.com/ipfs/go-ipfs/merkledag"
13 path "github.com/ipfs/go-ipfs/path"
14 unixfs "github.com/ipfs/go-ipfs/unixfs"
15 + uio "github.com/ipfs/go-ipfs/unixfs/io"
16 unixfspb "github.com/ipfs/go-ipfs/unixfs/pb"
17 )
18
@@ -87,7 +88,13 @@ possible, please use 'ipfs ls' instead.
88
89 for _, fpath := range paths {
90 ctx := req.Context()
90 - merkleNode, err := core.Resolve(ctx, node, path.Path(fpath))
91 +
92 + resolver := &path.Resolver{
93 + DAG: node.DAG,
94 + ResolveOnce: uio.ResolveUnixfsOnce,
95 + }
96 +
97 + merkleNode, err := core.Resolve(ctx, node.Namesys, resolver, path.Path(fpath))
98 if err != nil {
99 res.SetError(err, cmds.ErrNormal)
100 return
core/core.go
+2 -2
@@ -60,7 +60,7 @@ import (
60 pin "github.com/ipfs/go-ipfs/pin"
61 repo "github.com/ipfs/go-ipfs/repo"
62 config "github.com/ipfs/go-ipfs/repo/config"
63 - uio "github.com/ipfs/go-ipfs/unixfs/io"
63 + ft "github.com/ipfs/go-ipfs/unixfs"
64 u "gx/ipfs/Qmb912gdngC1UWwTkhuW8knyRbcWeu5kqkxBpveLmW8bSr/go-ipfs-util"
65 )
66
@@ -504,7 +504,7 @@ func (n *IpfsNode) loadFilesRoot() error {
504
505 switch {
506 case err == ds.ErrNotFound || val == nil:
507 - nd = uio.NewEmptyDirectory()
507 + nd = ft.EmptyDirNode()
508 _, err := n.DAG.Add(nd)
509 if err != nil {
510 return fmt.Errorf("failure writing to dagstore: %s", err)
core/corehttp/gateway_handler.go
+18 -5
@@ -17,6 +17,7 @@ import (
17 dag "github.com/ipfs/go-ipfs/merkledag"
18 dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
19 path "github.com/ipfs/go-ipfs/path"
20 + ft "github.com/ipfs/go-ipfs/unixfs"
21 uio "github.com/ipfs/go-ipfs/unixfs/io"
22
23 humanize "gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize"
@@ -153,7 +154,13 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
154 ipnsHostname = true
155 }
156
156 - nd, err := core.Resolve(ctx, i.node, path.Path(urlPath))
157 + p, err := path.ParsePath(urlPath)
158 + if err != nil {
159 + webError(w, "Invalid Path Error", err, http.StatusBadRequest)
160 + return
161 + }
162 +
163 + nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p)
164 // If node is in offline mode the error code and message should be different
165 if err == core.ErrNoNamesys && !i.node.OnlineMode() {
166 w.WriteHeader(http.StatusServiceUnavailable)
@@ -240,8 +247,14 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
247 return
248 }
249
250 + p, err := path.ParsePath(urlPath + "/index.html")
251 + if err != nil {
252 + internalWebError(w, err)
253 + return
254 + }
255 +
256 // return index page instead.
244 - nd, err := core.Resolve(ctx, i.node, path.Path(urlPath+"/index.html"))
257 + nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p)
258 if err != nil {
259 internalWebError(w, err)
260 return
@@ -356,7 +369,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
369
370 var newnode node.Node
371 if rsegs[len(rsegs)-1] == "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" {
359 - newnode = uio.NewEmptyDirectory()
372 + newnode = ft.EmptyDirNode()
373 } else {
374 putNode, err := i.newDagFromReader(r.Body)
375 if err != nil {
@@ -372,7 +385,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
385 }
386
387 var newcid *cid.Cid
375 - rnode, err := core.Resolve(ctx, i.node, rootPath)
388 + rnode, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, rootPath)
389 switch ev := err.(type) {
390 case path.ErrNoLink:
391 // ev.Node < node where resolve failed
@@ -397,7 +410,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
410 }
411
412 e := dagutils.NewDagEditor(pbnd, i.node.DAG)
400 - err = e.InsertNodeAtPath(ctx, newPath, newnode, uio.NewEmptyDirectory)
413 + err = e.InsertNodeAtPath(ctx, newPath, newnode, ft.EmptyDirNode)
414 if err != nil {
415 webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
416 return
core/corerepo/pinning.go
+6 -1
@@ -27,7 +27,12 @@ import (
27 func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]*cid.Cid, error) {
28 dagnodes := make([]node.Node, 0)
29 for _, fpath := range paths {
30 - dagnode, err := core.Resolve(ctx, n, path.Path(fpath))
30 + p, err := path.ParsePath(fpath)
31 + if err != nil {
32 + return nil, err
33 + }
34 +
35 + dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, p)
36 if err != nil {
37 return nil, fmt.Errorf("pin: %s", err)
38 }
core/coreunix/cat.go
+1 -1
@@ -9,7 +9,7 @@ import (
9 )
10
11 func Cat(ctx context.Context, n *core.IpfsNode, pstr string) (*uio.DagReader, error) {
12 - dagNode, err := core.Resolve(ctx, n, path.Path(pstr))
12 + dagNode, err := core.Resolve(ctx, n.Namesys, n.Resolver, path.Path(pstr))
13 if err != nil {
14 return nil, err
15 }
core/pathresolver.go
+7 -6
@@ -5,6 +5,7 @@ import (
5 "errors"
6 "strings"
7
8 + namesys "github.com/ipfs/go-ipfs/namesys"
9 path "github.com/ipfs/go-ipfs/path"
10
11 node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
@@ -18,13 +19,13 @@ var ErrNoNamesys = errors.New(
19
20 // Resolve resolves the given path by parsing out protocol-specific
21 // entries (e.g. /ipns/<node-key>) and then going through the /ipfs/
21 -// entries and returning the final merkledag node.
22 -func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (node.Node, error) {
22 +// entries and returning the final node.
23 +func Resolve(ctx context.Context, nsys namesys.NameSystem, r *path.Resolver, p path.Path) (node.Node, error) {
24 if strings.HasPrefix(p.String(), "/ipns/") {
25 // resolve ipns paths
26
27 // TODO(cryptix): we sould be able to query the local cache for the path
27 - if n.Namesys == nil {
28 + if nsys == nil {
29 return nil, ErrNoNamesys
30 }
31
@@ -40,7 +41,7 @@ func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (node.Node, error) {
41 return nil, err
42 }
43
43 - respath, err := n.Namesys.Resolve(ctx, resolvable.String())
44 + respath, err := nsys.Resolve(ctx, resolvable.String())
45 if err != nil {
46 return nil, err
47 }
@@ -53,7 +54,7 @@ func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (node.Node, error) {
54 }
55
56 // ok, we have an ipfs path now (or what we'll treat as one)
56 - return n.Resolver.ResolvePath(ctx, p)
57 + return r.ResolvePath(ctx, p)
58 }
59
60 // ResolveToKey resolves a path to a key.
@@ -76,7 +77,7 @@ func ResolveToCid(ctx context.Context, n *IpfsNode, p path.Path) (*cid.Cid, erro
77 if err != nil {
78 return nil, err
79 }
79 - dagnode, err := Resolve(ctx, n, head)
80 + dagnode, err := Resolve(ctx, n.Namesys, n.Resolver, head)
81 if err != nil {
82 return nil, err
83 }
core/pathresolver_test.go
+3 -3
@@ -14,17 +14,17 @@ func TestResolveNoComponents(t *testing.T) {
14 t.Fatal("Should have constructed a mock node", err)
15 }
16
17 - _, err = core.Resolve(n.Context(), n, path.Path("/ipns/"))
17 + _, err = core.Resolve(n.Context(), n.Namesys, n.Resolver, path.Path("/ipns/"))
18 if err != path.ErrNoComponents {
19 t.Fatal("Should error with no components (/ipns/).", err)
20 }
21
22 - _, err = core.Resolve(n.Context(), n, path.Path("/ipfs/"))
22 + _, err = core.Resolve(n.Context(), n.Namesys, n.Resolver, path.Path("/ipfs/"))
23 if err != path.ErrNoComponents {
24 t.Fatal("Should error with no components (/ipfs/).", err)
25 }
26
27 - _, err = core.Resolve(n.Context(), n, path.Path("/../.."))
27 + _, err = core.Resolve(n.Context(), n.Namesys, n.Resolver, path.Path("/../.."))
28 if err != path.ErrBadPath {
29 t.Fatal("Should error with invalid path.", err)
30 }
fuse/ipns/ipns_unix.go
+1 -1
@@ -94,7 +94,7 @@ func loadRoot(ctx context.Context, rt *keyRoot, ipfs *core.IpfsNode, name string
94 return nil, err
95 }
96
97 - node, err := core.Resolve(ctx, ipfs, p)
97 + node, err := core.Resolve(ctx, ipfs.Namesys, ipfs.Resolver, p)
98 if err != nil {
99 log.Errorf("looking up %s: %s", p, err)
100 return nil, err
path/resolver.go
+24 -7
@@ -7,7 +7,7 @@ import (
7 "fmt"
8 "time"
9
10 - merkledag "github.com/ipfs/go-ipfs/merkledag"
10 + dag "github.com/ipfs/go-ipfs/merkledag"
11
12 logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
13 node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
@@ -32,8 +32,19 @@ func (e ErrNoLink) Error() string {
32
33 // Resolver provides path resolution to IPFS
34 // It has a pointer to a DAGService, which is uses to resolve nodes.
35 +// TODO: now that this is more modular, try to unify this code with the
36 +// the resolvers in namesys
37 type Resolver struct {
36 - DAG merkledag.DAGService
38 + DAG dag.DAGService
39 +
40 + ResolveOnce func(ctx context.Context, ds dag.DAGService, nd node.Node, name string) (*node.Link, error)
41 +}
42 +
43 +func NewBasicResolver(ds dag.DAGService) *Resolver {
44 + return &Resolver{
45 + DAG: ds,
46 + ResolveOnce: ResolveSingle,
47 + }
48 }
49
50 // SplitAbsPath clean up and split fpath. It extracts the first component (which
@@ -53,7 +64,9 @@ func SplitAbsPath(fpath Path) (*cid.Cid, []string, error) {
64 }
65
66 c, err := cid.Decode(parts[0])
67 + // first element in the path is a cid
68 if err != nil {
69 + log.Debug("given path element is not a cid.\n")
70 return nil, nil, err
71 }
72
@@ -75,6 +88,11 @@ func (s *Resolver) ResolvePath(ctx context.Context, fpath Path) (node.Node, erro
88 return nodes[len(nodes)-1], err
89 }
90
91 +func ResolveSingle(ctx context.Context, ds dag.DAGService, nd node.Node, name string) (*node.Link, error) {
92 + lnk, _, err := nd.ResolveLink([]string{name})
93 + return lnk, err
94 +}
95 +
96 // ResolvePathComponents fetches the nodes for each segment of the given path.
97 // It uses the first path component as a hash (key) of the first node, then
98 // resolves all other components walking the links, with ResolveLinks.
@@ -113,21 +131,20 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd node.Node, names []stri
131 defer cancel()
132
133 lnk, rest, err := nd.ResolveLink(names)
116 - if err == merkledag.ErrLinkNotFound {
117 - n := nd.Cid()
118 - return result, ErrNoLink{Name: names[0], Node: n}
134 + if err == dag.ErrLinkNotFound {
135 + return result, ErrNoLink{Name: names[0], Node: nd.Cid()}
136 } else if err != nil {
137 return result, err
138 }
139
123 - nextnode, err := s.DAG.Get(ctx, lnk.Cid)
140 + nextnode, err := lnk.GetNode(ctx, s.DAG)
141 if err != nil {
142 return result, err
143 }
144
145 nd = nextnode
129 - names = rest
146 result = append(result, nextnode)
147 + names = rest
148 }
149 return result, nil
150 }
path/resolver_test.go
+1 -1
@@ -55,7 +55,7 @@ func TestRecurivePathResolution(t *testing.T) {
55 t.Fatal(err)
56 }
57
58 - resolver := &path.Resolver{DAG: dagService}
58 + resolver := path.NewBasicResolver(dagService)
59 node, err := resolver.ResolvePath(ctx, p)
60 if err != nil {
61 t.Fatal(err)
unixfs/io/resolve.go new
+46
@@ -0,0 +1,46 @@
1 +package io
2 +
3 +import (
4 + "context"
5 +
6 + dag "github.com/ipfs/go-ipfs/merkledag"
7 + ft "github.com/ipfs/go-ipfs/unixfs"
8 +
9 + node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
10 +)
11 +
12 +func ResolveUnixfsOnce(ctx context.Context, ds dag.DAGService, nd node.Node, name string) (*node.Link, error) {
13 + pbnd, ok := nd.(*dag.ProtoNode)
14 + if !ok {
15 + lnk, _, err := nd.ResolveLink([]string{name})
16 + return lnk, err
17 + }
18 +
19 + upb, err := ft.FromBytes(pbnd.Data())
20 + if err != nil {
21 + // Not a unixfs node, use standard object traversal code
22 + lnk, _, err := nd.ResolveLink([]string{name})
23 + return lnk, err
24 + }
25 +
26 + switch upb.GetType() {
27 + /*
28 + case ft.THAMTShard:
29 + s, err := hamt.NewHamtFromDag(ds, nd)
30 + if err != nil {
31 + return nil, err
32 + }
33 +
34 + // TODO: optimized routine on HAMT for returning a dag.Link to avoid extra disk hits
35 + out, err := s.Find(ctx, name)
36 + if err != nil {
37 + return nil, err
38 + }
39 +
40 + return dag.MakeLink(out)
41 + */
42 + default:
43 + lnk, _, err := nd.ResolveLink([]string{name})
44 + return lnk, err
45 + }
46 +}