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!)