func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, set key.KeySet) error { toprocess := make(chan []key.Key, 8) nodes := make(chan *NodeOption, 8) ctx, cancel := context.WithCancel(ctx) defer cancel() defer close(toprocess) go fetchNodes(ctx, ds, toprocess, nodes) nodes <- &NodeOption{Node: root} live := 1 for { select { case opt, ok := <-nodes: if !ok { return nil } if opt.Err != nil { return opt.Err } nd := opt.Node // a node has been fetched live-- var keys []key.Key for _, lnk := range nd.Links { k := key.Key(lnk.Hash) if !set.Has(k) { set.Add(k) live++ keys = append(keys, k) } } if live == 0 { return nil } if len(keys) > 0 { select { case toprocess <- keys: case <-ctx.Done(): return ctx.Err() } } case <-ctx.Done(): return ctx.Err() } } }
func Descendants(ctx context.Context, ds dag.DAGService, set key.KeySet, roots []key.Key, bestEffort bool) error { for _, k := range roots { set.Add(k) nd, err := ds.Get(ctx, k) if err != nil { return err } // EnumerateChildren recursively walks the dag and adds the keys to the given set err = dag.EnumerateChildren(ctx, ds, nd, set, bestEffort) if err != nil { return err } } return nil }
func Descendants(ds dag.DAGService, set key.KeySet, roots []key.Key) error { for _, k := range roots { set.Add(k) nd, err := ds.Get(context.Background(), k) if err != nil { return err } // EnumerateChildren recursively walks the dag and adds the keys to the given set err = dag.EnumerateChildren(context.Background(), ds, nd, set) if err != nil { return err } } return nil }
// EnumerateChildren will walk the dag below the given root node and add all // unseen children to the passed in set. // TODO: parallelize to avoid disk latency perf hits? func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, set key.KeySet) error { for _, lnk := range root.Links { k := key.Key(lnk.Hash) if !set.Has(k) { set.Add(k) child, err := ds.Get(ctx, k) if err != nil { return err } err = EnumerateChildren(ctx, ds, child, set) if err != nil { return err } } } return nil }
// EnumerateChildren will walk the dag below the given root node and add all // unseen children to the passed in set. // TODO: parallelize to avoid disk latency perf hits? func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, set key.KeySet, bestEffort bool) error { for _, lnk := range root.Links { k := key.Key(lnk.Hash) if !set.Has(k) { set.Add(k) child, err := ds.Get(ctx, k) if err != nil { if bestEffort && err == ErrNotFound { continue } else { return err } } err = EnumerateChildren(ctx, ds, child, set, bestEffort) if err != nil { return err } } } return nil }