github.com/ethersphere/bee/v2@v2.2.0/pkg/manifest/mantaray/walker.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mantaray
     6  
     7  import (
     8  	"context"
     9  	"sort"
    10  )
    11  
    12  // WalkNodeFunc is the type of the function called for each node visited
    13  // by WalkNode.
    14  type WalkNodeFunc func(path []byte, node *Node, err error) error
    15  
    16  func walkNodeFnCopyBytes(path []byte, node *Node, walkFn WalkNodeFunc) error {
    17  	return walkFn(append(path[:0:0], path...), node, nil)
    18  }
    19  
    20  // walkNode recursively descends path, calling walkFn.
    21  func walkNode(ctx context.Context, path []byte, l Loader, n *Node, walkFn WalkNodeFunc) error {
    22  	if n.forks == nil {
    23  		if err := n.load(ctx, l); err != nil {
    24  			return err
    25  		}
    26  	}
    27  
    28  	err := walkNodeFnCopyBytes(path, n, walkFn)
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	keys := make([]byte, 0, len(n.forks))
    34  	for k := range n.forks {
    35  		keys = append(keys, k)
    36  	}
    37  	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
    38  
    39  	for _, k := range keys {
    40  		v := n.forks[k]
    41  		nextPath := append(path[:0:0], path...)
    42  		nextPath = append(nextPath, v.prefix...)
    43  
    44  		err := walkNode(ctx, nextPath, l, v.Node, walkFn)
    45  		if err != nil {
    46  			return err
    47  		}
    48  	}
    49  
    50  	return nil
    51  }
    52  
    53  // WalkNode walks the node tree structure rooted at root, calling walkFn for
    54  // each node in the tree, including root. All errors that arise visiting nodes
    55  // are filtered by walkFn.
    56  func (n *Node) WalkNode(ctx context.Context, root []byte, l Loader, walkFn WalkNodeFunc) error {
    57  	node, err := n.LookupNode(ctx, root, l)
    58  	if err != nil {
    59  		err = walkFn(root, nil, err)
    60  	} else {
    61  		err = walkNode(ctx, root, l, node, walkFn)
    62  	}
    63  	return err
    64  }