Unverified Commit 44af1145 authored by Eric Myhre's avatar Eric Myhre Committed by GitHub

Merge pull request #51 from ipld/traversal-skip-control

traversal.SkipMe feature
parents 23298ebc 81c626ef
......@@ -54,3 +54,16 @@ type Config struct {
// could decide what kind of native type is expected, and return a
// `bind.NodeBuilder` for that specific concrete native type.
type LinkTargetNodeStyleChooser func(ipld.Link, ipld.LinkContext) (ipld.NodeStyle, error)
// SkipMe is a signalling "error" which can be used to tell traverse to skip some data.
//
// SkipMe can be returned by the Config.LinkLoader to skip entire blocks without aborting the walk.
// (This can be useful if you know you don't have data on hand,
// but want to continue the walk in other areas anyway;
// or, if you're doing a way where you know that it's valid to memoize seen
// areas based on Link alone.)
type SkipMe struct{}
func (SkipMe) Error() string {
return "skip"
}
......@@ -57,6 +57,8 @@ func WalkTransforming(n ipld.Node, s selector.Selector, fn TransformFn) (ipld.No
// This is important to note because when walking DAGs with Links,
// it means you may visit the same node multiple times
// due to having reached it via a different path.
// (You can prevent this by using a LinkLoader function which memoizes a set of
// already-visited Links, and returns a SkipMe when encountering them again.)
//
// WalkMatching (and the other traversal functions) can be used again again inside the VisitFn!
// By using the traversal.Progress handed to the VisitFn,
......@@ -122,6 +124,9 @@ func (prog Progress) walkAdv_iterateAll(n ipld.Node, s selector.Selector, fn Adv
progNext.LastBlock.Link = lnk
v, err = progNext.loadLink(v, n)
if err != nil {
if _, ok := err.(SkipMe); ok {
return nil
}
return err
}
}
......@@ -151,6 +156,9 @@ func (prog Progress) walkAdv_iterateSelective(n ipld.Node, attn []ipld.PathSegme
progNext.LastBlock.Link = lnk
v, err = progNext.loadLink(v, n)
if err != nil {
if _, ok := err.(SkipMe); ok {
return nil
}
return err
}
}
......@@ -189,6 +197,9 @@ func (prog Progress) loadLink(v ipld.Node, parent ipld.Node) (ipld.Node, error)
prog.Cfg.LinkLoader,
)
if err != nil {
if _, ok := err.(SkipMe); ok {
return nil, err
}
return nil, fmt.Errorf("error traversing node at %q: could not load link %q: %s", prog.Path, lnk, err)
}
return nb.Build(), nil
......
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