func traverse[T Block]()

in dag.go [132:177]


func traverse[T Block](d *Dag, f func(b T) error) error {
	var err error
	pending := linkedlistqueue.New()
	visited := hashset.New()
	for _, i := range d.GetRoots() {
		pending.Enqueue(i)
	}
	for !pending.Empty() {
		next, _ := pending.Dequeue()
		if visited.Contains(next) {
			continue
		}
		nb := next.(Block)
		address := nb.Address()
		parents, parentErr := d.GetParents(address)
		if parentErr != nil {
			return parentErr
		}
		ready := true
		for _, p := range parents {
			if !visited.Contains(p) {
				ready = false
				break
			}
		}
		if !ready {
			pending.Enqueue(next)
			continue
		}

		visited.Add(next)
		if b, ok := nb.(T); ok {
			if subError := f(b); subError != nil {
				err = multierror.Append(err, subError)
			}
		}
		children, getChildrenErr := d.GetChildren(address)
		if getChildrenErr != nil {
			return getChildrenErr
		}
		for _, c := range children {
			pending.Enqueue(c)
		}
	}
	return err
}