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 }