github.com/ipld/go-ipld-prime@v0.21.0/traversal/doc.go (about) 1 // Package traversal provides functional utilities for traversing and 2 // transforming IPLD graphs. 3 // 4 // Two primary types of traversal are implemented in this package: "Focus" and 5 // "Walk". Both types have a "Transforming" variant, which supports mutation 6 // through emulated copy-on-write tree rebuilding. 7 // 8 // Traversal operations use the Progress type for configuration and state 9 // tracking. Helper functions such as Focus and Walk exist to avoid manual setup 10 // of a Progress struct, but they cannot cross link boundaries without a 11 // LinkSystem, which needs to be configured on the Progress struct. 12 // 13 // A typical traversal operation involves creating a Progress struct, setting up 14 // the LinkSystem, and calling one of the Focus or Walk functions on the 15 // Progress object. Various other configuration options are available when 16 // traversing this way. 17 // 18 // # Focus 19 // 20 // "Focus" and "Get" functions provide syntactic sugar for using ipld.Path to 21 // access Nodes deep within a graph. 22 // 23 // "FocusedTransform" resembles "Focus" but supports user-defined mutation using 24 // its TransformFn. 25 // 26 // # Walk 27 // 28 // "Walk" functions perform a recursive walk of a Node graph, applying visitor 29 // functions to matched parts of the graph. 30 // 31 // The selector sub-package offers a declarative mechanism for guiding 32 // traversals and filtering relevant Nodes. 33 // (Refer to the selector sub-package for more details.) 34 // 35 // "WalkLocal" is a special case of Walk that doesn't require a selector. It 36 // walks a local graph, not crossing link boundaries, and calls its VisitFn for 37 // each encountered Node. 38 // 39 // "WalkMatching" traverses according to a selector, calling the VisitFn for 40 // each match based on the selector's matching rules. 41 // 42 // "WalkAdv" performs the same traversal as WalkMatching, but calls its 43 // AdvVisitFn on every Node, regardless of whether it matches the selector. 44 // 45 // "WalkTransforming" resembles "WalkMatching" but supports user-defined 46 // mutation using its TransformFn. 47 // 48 // # Usage Notes 49 // 50 // These functions work via callbacks, performing traversal and calling a 51 // user-provided function with a handle to the reached Node(s). Further "Focus" 52 // and "Walk" operations can be performed recursively within this callback if 53 // desired. 54 // 55 // All traversal functions operate on a Progress object, except "WalkLocal", 56 // which can be configured with a LinkSystem for automatic resolution and 57 // loading of new Node trees when IPLD Links are encountered. 58 // 59 // The "*Transform" methods are best suited for point-mutation patterns. For 60 // more general transformations, use the read-only systems (e.g., Focus, 61 // Traverse) and handle accumulation in the visitor functions. 62 // 63 // A common use case for walking traversal is running a selector over a graph 64 // and noting all the blocks it uses. This is achieved by configuring a 65 // LinkSystem that can handle and observe block loads. Be aware that a selector 66 // might visit the same block multiple times during a traversal, as IPLD graphs 67 // often form "diamond patterns" with the same block referenced from multiple 68 // locations. 69 // 70 // The LinkVisitOnlyOnce option can be used to avoid duplicate loads, but it 71 // must be used carefully with non-trivial selectors, where repeat visits of 72 // the same block may be essential for traversal or visit callbacks. 73 // 74 // A Budget can be set at the beginning of a traversal to limit the number of 75 // Nodes and/or Links encountered before failing the traversal (with the 76 // ErrBudgetExceeded error). 77 // 78 // The "Preloader" option provides a way to parallelize block loading in 79 // environments where block loading is a high-latency operation (such as 80 // fetching over the network). 81 // The traversal operation itself is not parallel and will proceed strictly 82 // according to path or selector order. However, a Preloader can be used to load 83 // blocks asynchronously, and prepare the LinkSystem that the traversal is using 84 // with already-loaded blocks. 85 // 86 // A Preloader and a Budget option can be used on the same traversal, BUT the 87 // Preloader may not receive the same links that the traversal wants to load 88 // from the LinkSystem. Use with care. See notes below. 89 package traversal 90 91 // Why only "point-mutation"? This use-case gets core library support because 92 // it's both high utility and highly clear how to implement it. 93 // More advanced transformations are nontrivial to provide generalized support 94 // for, for three reasons: efficiency is hard; not all existing research into 95 // categorical recursion schemes is necessarily applicable without modification 96 // (efficient behavior in a merkle-tree context is not the same as efficient 97 // behavior on uniform memory!); and we have the further compounding complexity 98 // of the range of choices available for underlying Node implementation. 99 // Therefore, attempts at generalization are not included here; handling these 100 // issues in concrete cases is easy, so we call it an application logic concern. 101 // However, exploring categorical recursion schemes as a library is encouraged!)