github.com/databricks/cli@v0.203.0/bundle/schema/tracker.go (about) 1 package schema 2 3 import ( 4 "container/list" 5 "fmt" 6 ) 7 8 type tracker struct { 9 // Nodes encountered in current path during the recursive traversal. Used to 10 // check for cycles 11 seenNodes map[interface{}]struct{} 12 13 // List of node names encountered in order in current path during the recursive traversal. 14 // Used to hydrate errors with path to the exact node where error occured. 15 // 16 // NOTE: node and node names can be the same 17 listOfNodes *list.List 18 } 19 20 func newTracker() *tracker { 21 return &tracker{ 22 seenNodes: map[interface{}]struct{}{}, 23 listOfNodes: list.New(), 24 } 25 } 26 27 func (t *tracker) errWithTrace(prefix string, initTrace string) error { 28 traceString := initTrace 29 curr := t.listOfNodes.Front() 30 for curr != nil { 31 if curr.Value.(string) != "" { 32 traceString += " -> " + curr.Value.(string) 33 } 34 curr = curr.Next() 35 } 36 return fmt.Errorf(prefix + ". traversal trace: " + traceString) 37 } 38 39 func (t *tracker) hasCycle(node interface{}) bool { 40 _, ok := t.seenNodes[node] 41 return ok 42 } 43 44 func (t *tracker) push(node interface{}, name string) { 45 t.seenNodes[node] = struct{}{} 46 t.listOfNodes.PushBack(name) 47 } 48 49 func (t *tracker) pop(nodeType interface{}) { 50 back := t.listOfNodes.Back() 51 t.listOfNodes.Remove(back) 52 delete(t.seenNodes, nodeType) 53 }